No default Instance is registered and cannot be automatically determined for type 'Mediachase.Commerce.Markets.IMarketService'

Vote:
 

Hi,

I have recently upgraded my episerver versions from 8.1 to 9.5. When everything seem to look ok, I am getting an isssue fetching few basic commerce elements. i am getting the below errors when trying to fetch things from the commerce data.

- No default Instance is registered and cannot be automatically determined for type 'Mediachase.Commerce.Markets.IMarketService'

- No default Instance is registered and cannot be automatically determined for type 'Mediachase.Commerce.Inventory.IWarehouseRepository'

The code causing this issue is:

var marketService = ServiceLocator.Current.GetInstance();

This may be because of structurmap being upgraded to >3.0. The only change of code is the below, which sounds the app.config assemblies may be not loaded in the memory.

IOC Set up// setup IoC
//ObjectFactory.Initialize(r => r.PullConfigurationFromAppConfig = true);
ObjectFactory.Initialize(); //TODO: Correct this as the upgrade is causing issue with this statement.

Any advice will be greatly appreciated?

Regards,

Ram

#143668
Jan 28, 2016 16:03
Vote:
 

You should not initialize StructureMap container yourself. Instead use IConfigurableModule

Here is an example of it:

[ModuleDependency(typeof(ServiceContainerInitialization))]
[InitializableModule]
public class DependencyResolverInitialization : IConfigurableModule
{
	public void ConfigureContainer(ServiceConfigurationContext context)
	{
		context.Container.Configure(ConfigureContainer);

		// This will setup the DependencyResolver with the EPiServer StructureMap Container
		DependencyResolver.SetResolver(new StructureMapDependencyResolver(context.Container));
	}

	private static void ConfigureContainer(ConfigurationExpression container)
	{
		container.AddRegistry<StructureMapRegistry>();
	}

	public void Initialize(InitializationEngine context)
	{
	}

	public void Uninitialize(InitializationEngine context)
	{
	}
}
#143706
Jan 29, 2016 8:57
Vote:
 

Hi,

You should not get those errors - what would you get if you call ServiceLocator.Current.GetInstance<ICurrentMarket>(); in your code?

Do you have custom implementation of IMarketService or IWarehouseRepository?

Regards,

/Q

#143711
Jan 29, 2016 9:26
Vote:
 

Hi Guys,

Thanks for your response.

But i some how feel the issue has occured after the flag "PullConfigurationFromAppConfig" was taken off from ObjectFactory initialisation, as it has become obselete after StructureMap was upgraded.

In simple terms, I would like to initialize structure map from assemblies from the config like in the older version of structure map. Is this possible or do i have to manually include all assemblies?

Maris in reading, if I want to use IConfigurableModule, will it automatically scan all the assemblies or do I have to manually include them?

Please point me to the right direction. Your time is very much appreciated.

Regards,

R

#143715
Jan 29, 2016 9:53
Vote:
 

If you have this in your web.config

<episerver.framework>
<scanAssembly forceBinFolderScan="true" />
<appData basePath="appData" />
</episerver.framework>

you should be fine. Framework will scan the bin folder and do the registration needed.

Regards,

/Q

#143716
Jan 29, 2016 10:00
Vote:
 

http://structuremap.github.io/registration/

StructureMap no longer supports Xml configuration or MEF-style attribute configuration -- but there is some facility for rolling your own attribute-based configuration support.

It seems that XML configuration not supported anymore.

#143717
Edited, Jan 29, 2016 10:08
Vote:
 

Scanning of the assemblies can be configured on the container (within StructureMap registry, for example):

Scan(x =>
            {
                x.TheCallingAssembly();
                x.WithDefaultConventions();
            });

Here it scans calling assembly, but other methods available too:

http://structuremap.github.io/registration/auto-registration-and-conventions/

Also do not use ObjectFactory directly - it might not configure same instance of container as EPiServer. You should use configuration module I mentioned before.

#143718
Edited, Jan 29, 2016 10:12
Vote:
 
<p>Hi Quan,</p> <p>My application is a windows service (this service picks up feed files and update database with products and variants) not a web application so no web.config (app.config exists). Tried adding your sugestion in the config and it did not like it.</p> <p>There should be a simple way to initialize either the object factory or container to scan all the assemblies. My structure map version is 3.16 by the way as episerver libraries won't let me upgrade to 4 because of depencencies.</p> <p>Maris in reading, the&nbsp;IConfigurableModule you mentioned, will it work in 3.16? If so can you please provide the using namespaces? as mine is not resolving.</p> <p>Thanks again guys,</p> <p>R</p>
#143756
Jan 29, 2016 15:52
Vote:
 
<p>IConfigurableModule is an EPiServer's interface. And it loads within EPiServer Web not windows service.</p> <p>I haven't work with windows service or command line apps within EPiServer context. I would suggest you to better use Service API to import products and variants than loading EPiServer context into windows service.</p> <p>Here is the documentation on Service API:</p> <p><a href="/documentation/Items/Episerver-Service-API/">http://world.episerver.com/documentation/Items/Episerver-Service-API/</a></p> <p>Your windows service can use this Service API to do importing instead.</p>
#143758
Jan 29, 2016 16:19
Vote:
 

Hi,

You can have something like this 

ObjectFactory.Initialize(init =>
{
init.Scan(t =>
{
t.AssembliesFromPath(@"<path-to-your-folder>"); 
t.Convention();
});
});

You can also have use a static method on a static class to override the dependencies configuration
 internal static class CatalogImportInitialization
    {
        public static void InitializeServiceLocator()
        {
            var container = new Container();
            var locator = new StructureMapServiceLocator(container);
            var context = new ServiceConfigurationContext(HostType.Installer, container);

            context.Container.Configure(ce =>
            {
                ce.For<IMarketService>().Singleton().Use<MarketServiceDatabase>();
            });

            ServiceLocator.SetLocator(locator);
        }
    }
#143761
Edited, Jan 29, 2016 16:30
Vote:
 
<p>Hi Quan,</p> <p>Sorry it took sometime for me to reply.<br />I have now tried your sugestion but still facing issues. See the below code when I run it I get the following exception.</p> <p></p> <pre class="brush:csharp;auto-links:false;toolbar:false" contenteditable="false"> var container = new Container(); var locator = new StructureMapServiceLocator(container); IServiceConfigurationProvider services = new StructureMapConfiguration(container); var context = new ServiceConfigurationContext(HostType.Installer, services); container.Configure(ce =&gt; { ce.For&lt;IMarketService&gt;().Singleton().Use&lt;MarketServiceDatabase&gt;(); ce.For&lt;IMarket&gt;().Singleton().Use&lt;MarketImpl&gt;(); ce.For&lt;ICurrentMarket&gt;().Singleton().Use&lt;CurrentMarketImpl&gt;(); ce.For&lt;ISynchronizedObjectInstanceCache&gt;().Singleton().Use&lt;RemoteCacheSynchronization&gt;(); ce.For&lt;IObjectInstanceCache&gt;().Singleton().Use&lt;HttpRuntimeCache&gt;(); ce.For&lt;ITypeScannerLookup&gt;().Singleton().Use&lt;FakeTypeScannerLookup&gt;(); ce.For&lt;IPriceService&gt;().Singleton().Use&lt;PriceServiceDatabase&gt;(); ce.For&lt;IPriceDetailService&gt;().Singleton().Use&lt;PriceDetailDatabase&gt;(); }); new EventsInitialization().ConfigureContainer(context); new CommerceInitialization().ConfigureContainer(context); new ServiceContainerInitialization().ConfigureContainer(context); ServiceLocator.SetLocator(locator);</pre> <p></p> <p>Exception:</p> <pre class="brush:csharp;auto-links:false;toolbar:false" contenteditable="false">Line causing the exception: new ServiceContainerInitialization().ConfigureContainer(context); Exception thrown: 'System.InvalidOperationException' in EPiServer.Framework.dll Additional information: No types to scan has been defined, could be caused by an InitializationEngine without a list of assemblies defined</pre> <p></p> <p><br />Can you think of anything obvious that I am missing?</p> <p>Thanks as always,<br />Ram</p>
#143884
Feb 02, 2016 18:09
Vote:
 

Also, I am not able to construct the ServiceConfigurationContext with both Services and Container, as the constructor accepts only either of the two, but both options fail with null reference exception of missing either Container or Services.

var context = new ServiceConfigurationContext(HostType.Installer, services);

Or

var context = new ServiceConfigurationContext(HostType.Installer, Container);

Thanks,
R

#143886
Feb 02, 2016 18:21
Vote:
 

Is the windows service on the same server as the website as techically you will need a license for server if it is not on the same server.  Also you will run into issues trying to run in this configuration.  Every time you upgrade you will face issues.  I would have the windows service call the service api to do updates or create your own api controllers that the service call call. Please see this thread for others attempting to initialize.

http://world.episerver.com/forum/developer-forum/EPiServer-Commerce/Thread-Container/2015/6/quartz-initialization-issues-after-episerver-82.x-upgrade/

#143887
Edited, Feb 02, 2016 19:57
Vote:
 
<p>Hi Mark,</p> <p>Thanks for your reply. The service I was talking about has seperate license, just to let you know it is a legacy system working A OK for the past few years. That being said, I have clearly defined, the issue is with the upgrade of the structure map and setting up the IOC. This service is being re written which will go to production in a month. This is purely a BAU to maintain the old system.</p> <p>Quan in reading, based on my previous reply is there a way where I can set both the services and container when initialising the&nbsp;ServiceConfigurationContext?</p> <p>Technically something like this:</p> <pre class="brush:csharp;auto-links:false;toolbar:false" contenteditable="false">var context = new ServiceConfigurationContext(HostType.Installer, services, container);</pre> <p>Thanks,</p> <p>Ram</p>
#143905
Feb 03, 2016 10:30
Vote:
 

Hi All,

I some how managed to sort the issue, thanks to Quan from episerver. The following code has kept me moving forward on the structuremap issue.

I hope this could be useful to someone.

            var container = new Container(config =>
            {
                config.Scan(scan =>
                {
                    scan.TheCallingAssembly();
                    scan.WithDefaultConventions();
                });
            });

            var locator = new StructureMapServiceLocator(container);
            var context = new ServiceConfigurationContext(HostType.Service, container);
            EventContext eventContext = (EventContext)typeof(EventContext).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null).Invoke(null);

            context.Container.Configure(ce =>
            {
                ce.For<IMarketService>().Use<MarketServiceDatabase>();
                ce.For<IMarket>().Use<MarketImpl>();
                ce.For<ICurrentMarket>().Use<CurrentMarketImpl>();
                ce.For<ISynchronizedObjectInstanceCache>().Use<RemoteCacheSynchronization>();
                ce.For<IObjectInstanceCache>().Use<HttpRuntimeCache>();
                ce.For<ITypeScannerLookup>().Use<FakeTypeScannerLookup>();
                ce.For<IWarehouseRepository>().Singleton().Use<WarehouseRepositoryDatabase>();
                ce.For<ISynchronizedObjectInstanceCache>().Singleton().Use<FakeInstanceObjectCache>();
                ce.For<IPriceService>().Singleton().Use<PriceServiceDatabase>();
                ce.For<IPriceDetailService>().Use<PriceDetailDatabase>();
                ce.For<IWarehouseInventoryService>().Singleton().Use<WarehouseInventoryProxy>();
                ce.For<IInventoryService>().Singleton().Use<InventoryServiceProvider>();
                ce.For<IApplicationContext>().Singleton().Use<ApplicationContext>();
                ce.For<CatalogConfiguration>().Use(CatalogConfiguration.Instance);
                ce.For<IRequiredMetaFieldCollection>().Singleton().Use<DefaultRequiredMetaFields>();
                ce.For<MetaDataContext>().Singleton().Use(() => CatalogContext.MetaDataContext);
                ce.For<EventContext>().HybridHttpOrThreadLocalScoped().Use(eventContext);
                ce.For<FrameworkContext>().Use(() => FrameworkContext.Current);
                ce.For<CatalogConfiguration>().Use(CatalogConfiguration.Instance);
                ce.For<SqlContext>().Use(() => new SqlContext(BusinessFoundationConfigurationSection.Instance.Connection.Database));
                ce.For<IChangeNotificationQueueFactory>().Singleton().Use<CommerceChangeQueueFactory>();
                ce.For<IChangeNotificationManager>().Singleton().Use<ChangeNotificationManager>();
                ce.For<ICatalogSystem>().Singleton().Use(() => CatalogContext.Current);
            });

            ServiceLocator.SetLocator(locator);

Thanks once again Quan.

Regards,
Ram

#144146
Feb 08, 2016 15:24
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.