Type initialization exception when accessing CustomerContext methods within a WCF service

Vote:
 

Im using EpiServer Commerce 7.5 and Im trying to retrieve organization information through CustomerContext method GetAllOrganization() in a WCF service application. However, when I try to call the method I get the following exception message:

 

"The type initializer for 'Mediachase.BusinessFoundation.Data.Meta.Management.TriggerManager' threw an exception."

"Activation error occurred while trying to get instance of type ITypeScannerLookup, key \"\""

"StructureMap Exception Code: 202\nNo Default Instance defined for PluginFamily EPiServer.Framework.TypeScanner.ITypeScannerLookup, EPiServer.Framework, Version=7.5.394.2, Culture=neutral, PublicKeyToken=8fe83dea738b45b7"

Stack:

   at Mediachase.BusinessFoundation.Data.Meta.Management.TriggerManager.AssignTransactionScope(TransactionScope tran)
   at Mediachase.BusinessFoundation.Data.TransactionScope..ctor(SqlTransactionScope transaction)
   at Mediachase.BusinessFoundation.Data.DataContext.BeginTransaction()
   at Mediachase.BusinessFoundation.Data.Business.BusinessManager.Execute(Request request)
   at Mediachase.BusinessFoundation.Data.Business.BusinessManager.List(String metaClassName, FilterElement[] filters)
   at Mediachase.Commerce.Customers.CustomerContext.<InnerGetAllOrganization>d__2.MoveNext()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at Mediachase.Commerce.Customers.CustomerContext.<GetAllOrganization>b__1()
   at Mediachase.Commerce.Customers.CustomerContext.GetCachedValue(String key, TimeSpan timeout, Func`1 cachedValueGetter)
   at Mediachase.Commerce.Customers.CustomerContext.GetAllOrganization()

    

I did some searching around the forum and made sure that I have initialized both SqlContext and DataContext before making the method call but this did not solve the problem. My guess it is an initialization problem but I am at loss what Im missing as I have copied my commerce config files and dll's to the bin folder plus the license file is at place.

 
#81777
Feb 26, 2014 12:14
Vote:
 

Hi,

Please make sure two things:

- Your application is properly configured. You will need a web.config/app.config which point to Configs folder. Take a look at normal web.config file, which has references to various config files in /Configs folder

- You initialized FrameworkInitialization properly.

 

Regards.

/Q

#81780
Feb 26, 2014 13:04
Vote:
 

Hi,

 

Here are my related configurations on my WCF web service web.config:

  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
<sectionGroup name="FrameworkProviders"> <section name="dataService" type="Mediachase.Data.Provider.DataProviderSection, Mediachase.DataProvider" /> </sectionGroup>
<sectionGroup name="CommerceFramework"> <section name="Workflow" type="Mediachase.Commerce.WorkflowConfiguration,Mediachase.Commerce" /> <section name="Application" type="Mediachase.Commerce.Core.CoreConfiguration,Mediachase.Commerce" /> <section name="Catalog" type="Mediachase.Commerce.Catalog.CatalogConfiguration,Mediachase.Commerce" /> <section name="Marketing" type="Mediachase.Commerce.Marketing.MarketingConfiguration,Mediachase.Commerce" /> <section name="Orders" type="Mediachase.Commerce.Orders.OrderConfiguration,Mediachase.Commerce" /> <section name="Security" type="Mediachase.Commerce.Security.Configuration.SecurityConfigurationSection,Mediachase.Commerce" /> <section name="Customers" type="Mediachase.Commerce.Customers.Configuration.CustomerConfiguration,Mediachase.Commerce" /> <section name="ContentManagement" type="Mediachase.Cms.CmsConfiguration,Mediachase.Cms" /> <section name="AssetManagement" type="Mediachase.Commerce.Assets.AssetConfiguration, Mediachase.Commerce" /> </sectionGroup>
<sectionGroup name="mediachase.businessFoundation.data" type="Mediachase.BusinessFoundation.Data.Configuration.MediachaseDataSectionGroup, Mediachase.BusinessFoundation.Data"> <section name="metaClassManager" type="Mediachase.BusinessFoundation.Data.Meta.Management.Configuration.MetaClassManagerSection, Mediachase.BusinessFoundation.Data" /> <section name="metaObject" type="Mediachase.BusinessFoundation.Data.Meta.Configuration.MetaObjectSection, Mediachase.BusinessFoundation.Data" /> <section name="businessManager" type="Mediachase.BusinessFoundation.Data.Business.Configuration.BusinessManagerSection, Mediachase.BusinessFoundation.Data" /> </sectionGroup>
<sectionGroup name="Mediachase.BusinessFoundation"> <section name="BusinessFoundationSettings" type="Mediachase.BusinessFoundation.Configuration.BusinessFoundationConfigurationSection, Mediachase.BusinessFoundation" /> </sectionGroup> <section name="episerver.framework" type="EPiServer.Framework.Configuration.EPiServerFrameworkSection, EPiServer.Framework" /> </configSections> <!-- Business Foundation Configuration --> <Mediachase.BusinessFoundation> <BusinessFoundationSettings configSource="Configs\baf.config" /> </Mediachase.BusinessFoundation> <mediachase.businessFoundation.data> <businessManager configSource="Configs\baf.data.manager.config" /> <metaObject configSource="Configs\baf.data.metaobject.config" /> </mediachase.businessFoundation.data> <!-- Framework configuration --> <CommerceFramework> <AssetManagement configSource="Configs\ecf.asset.config" /> <ContentManagement configSource="Configs\ecf.cms.config" /> <Workflow configSource="Configs\ecf.workflow.config" /> <Application configSource="Configs\ecf.app.config" /> <Catalog configSource="Configs\ecf.catalog.config" /> <Marketing configSource="Configs\ecf.marketing.config" /> <Orders configSource="Configs\ecf.order.config" /> <Customers configSource="Configs\ecf.customer.config" /> <Security configSource="Configs\ecf.security.config" /> </CommerceFramework> <episerver.framework configSource="Configs\EPiServerFramework.config" /> <!-- Framework Providers --> <FrameworkProviders> <dataService defaultProvider="SqlDataProvider"> <providers> <add name="SqlDataProvider" type="Mediachase.Data.Provider.SqlDataProvider, Mediachase.SqlDataProvider" connectionStringName="EcfSqlConnection" applicationName="EPiServerCommerceManager6" /> </providers> </dataService> </FrameworkProviders>

    

And here is the method I initialize the service locator with:

        /// <summary>
        /// Service locator initialization
        /// </summary>
        void InitializeServiceLocator()
        {
            var container = new StructureMap.Container();
            var locator = new EPiServer.ServiceLocation.StructureMapServiceLocator(container);
            var context = new EPiServer.ServiceLocation.ServiceConfigurationContext(HostType.Installer, container);

            context.Container.Configure(ce =>
            {
                ce.For<IRequiredMetaFieldCollection>().Singleton().Use<NoRequiredMetaFields>();

                ce.For<IWarehouseInventoryService>().Singleton().Use<CacheWarehouseInventoryService>()
                    .Ctor<IWarehouseInventoryService>().Is<Mediachase.Commerce.Inventory.Database.WarehouseInventoryServiceDatabase>()
                    .Ctor<TimeSpan>().Is(new TimeSpan(1, 0, 0));

                ce.For<IWarehouseRepository>().Singleton().Use<Mediachase.Commerce.Inventory.Database.WarehouseRepositoryDatabase>();
                ce.For<ISynchronizedObjectInstanceCache>().Singleton().Use<LocalCacheWrapper>();
                ce.For<ICatalogSystem>().Singleton().Use(() => CatalogContext.Current);
                ce.For<IChangeNotificationManager>().Singleton().Use<NullChangeNotificationManager>();
                ce.For<IPriceService>().Singleton().Use<Mediachase.Commerce.Pricing.Database.PriceServiceDatabase>();
            });
            
            if (SqlContext.Current == null)
            {
                SqlContext.Current = new SqlContext(ConfigurationManager.ConnectionStrings["EcfSqlConnection"].ConnectionString);
            }

            if (DataContext.Current == null)
            {
                DataContext.Current = new DataContext(ConfigurationManager.ConnectionStrings["EcfSqlConnection"].ConnectionString);
            }

            EPiServer.ServiceLocation.ServiceLocator.SetLocator(locator);
        }

    

With these configurations and initialization I can, for example, use OrderContext search methods without a problem to retrieve orders and manipulate them. But the CustomerContext I am baffled with and always end up with the "The type initializer for 'Mediachase.BusinessFoundation.Data.Meta.Management.TriggerManager' threw an exception."

#81799
Edited, Feb 26, 2014 15:51
Vote:
 

Hi,

Your config looks right, nice work! Your initialization code should be changed a bit:

public class YourClass : InitializationEnigne

{

     void InitializeServiceLocator()

     {

         //your code

         ConfigureContainer(HostType.Installer);

       

     }

}

Let me know if it works for you :).

Regards.

/Q

 

 

#81814
Feb 27, 2014 2:53
Vote:
 

Hi Markus Miettinen,

 

Did you find the solution? I am also getting the same exception Mediachase.BusinessFoundation.Data.Meta.Management.TriggerManager threw an exception.

 

#85372
Apr 24, 2014 4:21
Vote:
 

Hi,

 

I was able to resolve this issue by adding fake implementation for one of the interface

 var container = new StructureMap.Container();
            var locator = new StructureMapServiceLocator(container);
            var context = new ServiceConfigurationContext(HostType.Service, container);

            new Mediachase.Commerce.Initialization.CommerceInitialization().ConfigureContainer(context); 

            // Structure Map
            context.Container.Configure(s =>
                {
                    s.AddRegistry<InfrastructureRegistry>();
                });

            // Set EPiServer Locator service container to our defined structure map container
            ServiceLocator.SetLocator(locator);

            if (SqlContext.Current == null)
            {
                SqlContext.Current =
                    new SqlContext(ConfigurationManager.ConnectionStrings["EcfSqlConnection"].ConnectionString);
            }

            if (DataContext.Current == null)
            {
                DataContext.Current =
                    new DataContext(ConfigurationManager.ConnectionStrings["EcfSqlConnection"].ConnectionString);
            }

    in Infrastructure Regsitry

  For<IMarketService>().HybridHttpOrThreadLocalScoped().Use<MarketServiceDatabase>();
  For<IMarket>().HybridHttpOrThreadLocalScoped().Use<MarketImpl>();
  For<ICurrentMarket>().HybridHttpOrThreadLocalScoped().Use<CurrentMarketImpl>();
  For<ISynchronizedObjectInstanceCache>().HybridHttpOrThreadLocalScoped().Use<RemoteCacheSynchronization>();
  For<IObjectInstanceCache>().HybridHttpOrThreadLocalScoped().Use<RemoteCacheSynchronization>();
  For<ITypeScannerLookup>().HybridHttpOrThreadLocalScoped().Use<FakeTypeScannerLookup>();

    

 

#85381
Apr 24, 2014 8:21
Vote:
 

Yes, that was exactly what I had to do. I forgot to post the solution.

#85382
Apr 24, 2014 8:57
Vote:
 

I have same kind of issue but with a Quartz jobs, I tried to use your solution, but "InfrastructureRegistry" does not resolve for me. Which assembly does it live in?

 

Also I could not understand the Fake Implementation of an interface, would you mind sheding some light on it?

#85580
Apr 29, 2014 16:42
Vote:
 

Hi Azhar,

 

Infrastructure is the below class which contains the dependency injection initialization

 

 public class InfrastructureRegistry : Registry
    {
        public InfrastructureRegistry()
        {
            // Register your custom dependency below
            
            For<IRequiredMetaFieldCollection>().Use<NoRequiredMetaFields>();

            For<IMarketService>().HybridHttpOrThreadLocalScoped().Use<MarketServiceDatabase>();
            For<IMarket>().HybridHttpOrThreadLocalScoped().Use<MarketImpl>();
            For<ICurrentMarket>().HybridHttpOrThreadLocalScoped().Use<CurrentMarketImpl>();
            For<ISynchronizedObjectInstanceCache>().HybridHttpOrThreadLocalScoped().Use<RemoteCacheSynchronization>();
            For<IObjectInstanceCache>().HybridHttpOrThreadLocalScoped().Use<RemoteCacheSynchronization>();
            For<ITypeScannerLookup>().HybridHttpOrThreadLocalScoped().Use<FakeTypeScannerLookup>();

/* ... My Other custom class registration goes here
* ....
*/
        }
    }

    

The TypeScannerLookup is internal class of EPiServer so you cant provide it in structure map registration. so therefore, i created fake implementation class for the ITypeScannerLookup interface of EPiServer.

I got the implementation of this class from original EPiServer TypeScannerLookup clas

  /// <summary>
    /// Default implementation of <see cref="T:EPiServer.Framework.TypeScanner.ITypeScannerLookup"/>
    /// </summary>
    public class FakeTypeScannerLookup : ITypeScannerLookup
    {
        private static object _lock = new object();
        private HashSet<Type> _types = new HashSet<Type>();

        /// <summary>
        /// Gets the scanned types.
        /// 
        /// </summary>
        public IEnumerable<Type> AllTypes
        {
            get
            {
                return (IEnumerable<Type>)this._types;
            }
        }

        static FakeTypeScannerLookup()
        {
        }

        /// <summary>
        /// Adds the specified scanned type.
        /// 
        /// </summary>
        /// <param name="t">The t.</param>
        public void Add(Type t)
        {
            lock (_lock)
                this._types.Add(t);
        }

        /// <summary>
        /// Deletes the specified scanned type.
        /// 
        /// </summary>
        /// <param name="t">The t.</param>
        public void Delete(Type t)
        {
            this._types.Remove(t);
        }
    }

    

#85596
Edited, Apr 30, 2014 2:53
Vote:
 

I had problems getting it up and running as well, so I took Niklas Israelssons's Commerce Integration Test Sample project on Github and made it into a Console app.

https://github.com/nicklasisraelsson/EPiCommerce.Integration.Sample

#88612
Jul 18, 2014 19:56
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.