We're using it sucessfully. Are you sure the error is related? We're not using the integration package for mvc, this is how we usually set it up:
namespace EV { using System; using System.Collections.Generic; using System.Linq; using System.Web.Mvc; using StructureMap; public class StructureMapDependencyResolver : IDependencyResolver { private readonly IContainer container; public StructureMapDependencyResolver(IContainer container) { this.container = container; } public object GetService(Type serviceType) { if (serviceType.IsInterface || serviceType.IsAbstract) { return this.container.TryGetInstance(serviceType); } else { try { // Can't use TryGetInstance here because it won’t create concrete types return this.container.GetInstance(serviceType); } catch (StructureMapException) { return null; } } } public IEnumerable<object> GetServices(Type serviceType) { return this.container.GetAllInstances(serviceType).Cast<object>(); } } }
namespace DV { using System; using System.Collections.Generic; using System.Linq; using System.Web.Http.Dependencies; using StructureMap; public class StructureMapWebApiDependencyResolver : IDependencyResolver { private readonly IContainer container; public StructureMapWebApiDependencyResolver(IContainer container) { this.container = container; } public IDependencyScope BeginScope() { var childContainer = this.container.GetNestedContainer(); return new StructureMapWebApiDependencyResolver(childContainer); } public object GetService(Type serviceType) { if (serviceType.IsInterface || serviceType.IsAbstract) { return this.container.TryGetInstance(serviceType); } else { try { // Can't use TryGetInstance here because it won’t create concrete types return this.container.GetInstance(serviceType); } catch (StructureMapException) { return null; } } } public IEnumerable<object> GetServices(Type serviceType) { return this.container.GetAllInstances(serviceType).Cast<object>(); } public void Dispose() { this.container.Dispose(); } } }
And then in an module
namespace DV { using System.Web.Http; using System.Web.Mvc; using EPiServer.Framework; using EPiServer.Framework.Initialization; using EPiServer.ServiceLocation; [InitializableModule] [ModuleDependency(typeof(ServiceContainerInitialization))] public class ContainerConfigurableModule : IConfigurableModule { public void ConfigureContainer(ServiceConfigurationContext context) { // Configure for MVC DependencyResolver.SetResolver(new StructureMapDependencyResolver(context.Container)); // Configure for Web API GlobalConfiguration.Configuration.DependencyResolver = new StructureMapWebApiDependencyResolver(context.Container); } /// <summary> /// Exists because IConfigurableModule, not used at present time /// </summary> /// <param name="context">the InitializationEngine context</param> public void Initialize(InitializationEngine context) { } /// <summary> /// Exists because IConfigurableModule, not used at present time /// </summary> /// <param name="context">the InitializationEngine context</param> public void Uninitialize(InitializationEngine context) { } } }
Hey Johan, it's ASP.NET MVC that I'm after and which doesn't seem to work. The nested container approach works fine within WebAPI.
The nested container being created within
System.Web.Http.Dependencies.IDependencyResolver.BeginScope()
in your example only gets used by WebAPI. The other System.Web.Mvc.IDependencyResolver which gets passed to MVC uses the parent container from the context (ServiceConfigurationContext).
I'm actually very close to releasing a package on NuGet that can do it for MVC and WebAPI. The source is open on github if you want to try before then.
Here is the link to the docs: https://bmcdavid.github.io/DotNetStarter/.
The examples show how to use the Episerver container. Feel free to give it a try if you like.
-Brad
Nice! I'll check it out :)
I still think Episerver should be supporting nested containers for MVC out of the box though...
Here is a stripped down Gist that does what you need as well with the other stuff in the package.
https://gist.github.com/bmcdavid/ddceeb01cbddb3d8b62f70b5ffd4cf53
-Brad
Hey Tamim
Did yo manage to get it working? I tried it about a year - year and a half ago and could not get it working.
/David
Hey, I checked with Episerver who basically said they don't support nested containers. So one option is to use child containers instead - this is what Brad (see previously reply) has used in his solution.
I worked around the issue by only resolving my application specific dependencies through the nested container, essentially excluding all Episerver services, which seems to work.
I'm wondering if anyone has tried using the Nested Container feature from StructureMap in an Episerver website.
StructureMap recommends using nested containers to ensure object lifecycles are scoped to an http request, instead of using some of the legacy lifecycles such as HybridHttpOrThreadLocalScoped.
I tried to implement this in the Alloy sample website using the latest StructureMap.MVC5 nuget package and integrate it with the Container provided through the ConfigureContainer method in an IConfigurableModule module. The website seems to work fine until I hit one of the landing pages where I get this error. I suspect it is failing over when there are child controllers involved in the request pipeline.
Any thoughts?