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) { } }
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
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
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
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.
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.
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);
}
}
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
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/
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
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.
// 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