image

Extending Contact or Organization entity in business foundation Episerver commerce

image By - Ravindra Rathore
02 April 2021
 

Hi Guys,

Business Foundation is the main part of Episerver commerce solution because it is used for contact management, organization management but some time we need to extend its out of the box entity properties and add some custom properties according to our needs.

Today I am going to provide you the simple solution for this where you can add your custom properties in this so for this you need to follow below steps-

Step 1

Create a new class called “BusinessFoundationField” and defined some properties in this.

using Mediachase.BusinessFoundation.Data.Meta.Management;

namespace ABCProject.Web.Features.Utilities.MetaModelExtensions.Models
{
    public class BusinessFoundationField
    {
        public string Name { get; set; }

        public string FriendlyName { get; set; }

        public string Type { get; set; }

        public AttributeCollection Attributes { get; set; }
    }
}

Step 2

Create a new interface called “IBusinessFoundationService”

using ABCProject.Web.Features.Utilities.MetaModelExtensions.Models;
using Mediachase.BusinessFoundation.Data;

namespace ABCProject.Web.Features.Utilities.MetaModelExtensions.Services
{
    public interface IBusinessFoundationService
    {
        void CreateField(DataContext dataContext, BusinessFoundationField config, string className);
    }
}

Step 3

Now create one class called “BusinessFoundationService” using this interface.

using System;
using ABCProject.Web.Features.Utilities.MetaModelExtensions.Models;
using Mediachase.BusinessFoundation.Data;
using Mediachase.BusinessFoundation.Data.Meta.Management;

namespace ABCProject.Web.Features.Utilities.MetaModelExtensions.Services
{
    public class BusinessFoundationService : IBusinessFoundationService
    {
        public void CreateField(DataContext dataContext, BusinessFoundationField config, string className)
        {
            using (MetaClassManagerEditScope scope = dataContext.MetaModel.BeginEdit())
            {
                var metaClass = dataContext.MetaModel.MetaClasses[className];
                if (metaClass == null)
                    return;

                var metaField = metaClass.Fields[config.Name];
                if (metaField == null)
                {
                    metaField = metaClass.CreateMetaField(config.Name, config.FriendlyName, config.Type, config.Attributes);
                    scope.SaveChanges();
                }
                else if (!string.Equals(metaField.FriendlyName, config.FriendlyName, StringComparison.InvariantCultureIgnoreCase))
                {
                    metaField.FriendlyName = config.FriendlyName;
                    scope.SaveChanges();
                }
            }
        }
    }
}

Step 4

Now add a initialization module to register “IBusinessFoundationService” service so that we can use it when we will add new fields in Business Foundation entity.

using ABCProject.Web.Features.Utilities.MetaModelExtensions.Services;
using EPiServer.Framework;
using EPiServer.Framework.Initialization;
using EPiServer.ServiceLocation;

namespace ABCProject.Web.Infrastructure
{
    [InitializableModule]
    [ModuleDependency(typeof(EPiServer.Web.InitializationModule))]
    [ModuleDependency(typeof(EPiServer.Commerce.Initialization.InitializationModule))]
    public class SharedContainerInitialization : IConfigurableModule
    {
        void IConfigurableModule.ConfigureContainer(ServiceConfigurationContext context)
        {
            var services = context.Services;

            //B
            services.AddSingleton();
        }

        void IInitializableModule.Initialize(InitializationEngine context) { }

        void IInitializableModule.Uninitialize(InitializationEngine context) { }
    }
}

Step 5

Now create a new class where you will define all the new field that you want to add.

using ABCProject.Web.Features.Utilities.MetaModelExtensions.Models;
using Mediachase.BusinessFoundation.Data.Meta.Management;
using Mediachase.MetaDataPlus.Configurator;
using MetaField = Mediachase.BusinessFoundation.Data.Meta.Management.MetaField;

namespace ABCProject.Web.Features.Utilities.MetaModelExtensions.Constants
{
    public class BusinessFoundationFields
    {
        // Extending the contact entity
        public static readonly BusinessFoundationField MasterAccount = new BusinessFoundationField
        {
            Type = MetaFieldType.LongText,
            FriendlyName = "MasterAccount",
            Name = nameof(MasterAccount),
            Attributes = new AttributeCollection(),
        };

        public static readonly BusinessFoundationField UserType = new BusinessFoundationField
        {
            Type = MetaFieldType.Text,
            FriendlyName = "UserType",
            Name = nameof(UserType),
            Attributes = new AttributeCollection(),
        };

        // Extending the organization entity
        public static readonly BusinessFoundationField CustomOrganizationType = new BusinessFoundationField
        {
            Name = nameof(CustomOrganizationType),
            Type = MetaFieldType.Text,
            Attributes = new AttributeCollection(),
            FriendlyName = "Custom Organization Type",
        };

    }
}

Step 6

Now its time to add new field in the existing Business Foundation entity so for this we need to add one more initialization module where we will add our new fields.

using System;
using System.Linq;
using ABCProject.Web.Features.Utilities.MetaModelExtensions.Constants;
using ABCProject.Web.Features.Utilities.MetaModelExtensions.Services;
using EPiServer.Data;
using EPiServer.Framework;
using EPiServer.Framework.Initialization;
using EPiServer.ServiceLocation;
using Mediachase.BusinessFoundation.Data;
using Mediachase.BusinessFoundation.Data.Meta.Management;
using Mediachase.BusinessFoundation.MetaForm;
using Mediachase.Commerce.Customers;
using Mediachase.Data.Provider;

namespace ABCProject.Web.Infrastructure
{
    [InitializableModule]
    [ModuleDependency(typeof(EPiServer.Web.InitializationModule))]
    [ModuleDependency(typeof(EPiServer.Commerce.Initialization.InitializationModule))]
    public class MetaModelInitialization : IInitializableModule
    {
        public void Initialize(InitializationEngine context)
        
        {
            if (ServiceLocator.Current.GetInstance().DatabaseMode == DatabaseMode.ReadOnly)
                return;

            var connectionStringHandler = ServiceLocator.Current.GetInstance();
            InitializeBusinessFoundation(connectionStringHandler);
           
        }

        private static void InitializeBusinessFoundation(IConnectionStringHandler connectionStringHandler)
        {
            var businessFoundationService = ServiceLocator.Current.GetInstance();

            using (var dataContext = new DataContext(connectionStringHandler.Commerce.Name))
            {
                //Adding fields in Contact entity
                businessFoundationService.CreateField(dataContext, BusinessFoundationFields.MasterAccount, ContactEntity.ClassName);
                businessFoundationService.CreateField(dataContext, BusinessFoundationFields.UserType, ContactEntity.ClassName);
    

                //Adding fields in Organization entity
                businessFoundationService.CreateField(dataContext, BusinessFoundationFields.CustomOrganizationType, OrganizationEntity.ClassName);
             
            }
        }

        public void Uninitialize(InitializationEngine context) { }
    }
}

Step 7

Now press F5 and run the website and you will see the new fields in database, and you can use these field in your application.

To verify you can login into your SQL Server Management Studio (SSMS). Expand the commerce database and expand below tables and check the “Columns” in it.

image

Thanks for reading this blog post I hope it helps

Thanks and regards

Ravindra S. Rathore