How to get an instance of IContainer Structuremap from Asp.Net MVC 5 Dependency Resolver

I use Structuremap as my dependency resolver. I am trying to implement the Container Per Request template in the Global.asax.cs file.

public IContainer Container { get { return (IContainer)HttpContext.Current.Items["_Container"]; } set { HttpContext.Current.Items["_Container"] = value; } } public void Application_BeginRequest() { Container = ObjectFactory.Container.GetNestedContainer(); } 

Since ObjectFactory will not be supported in future versions of Structuremap, I would like to access the container from DependencyResolver. As possible?

Thanks at Advance.

Noufal

+5
source share
3 answers

Faced with this question myself, this was the best guide I could find for registering StructureMap using the ASP.NET MVC Dependency Resolver (via the CommonServiceLocator package ).

I copied and pasted the above solution for the article, but I would recommend taking advantage of this solution in the original article.

 public class StructureMapDependencyResolver : ServiceLocatorImplBase { private const string StructuremapNestedContainerKey = "Structuremap.Nested.Container"; public IContainer Container { get; set; } private HttpContextBase HttpContext { get { var ctx = Container.TryGetInstance<HttpContextBase>(); return ctx ?? new HttpContextWrapper(System.Web.HttpContext.Current); } } public IContainer CurrentNestedContainer { get { return (IContainer)HttpContext.Items[StructuremapNestedContainerKey]; } set { HttpContext.Items[StructuremapNestedContainerKey] = value; } } public StructureMapDependencyResolver(IContainer container) { Container = container; } protected override IEnumerable<object> DoGetAllInstances(Type serviceType) { return (CurrentNestedContainer ?? Container).GetAllInstances(serviceType).Cast<object>(); } protected override object DoGetInstance(Type serviceType, string key) { var container = (CurrentNestedContainer ?? Container); if (string.IsNullOrEmpty(key)) { return serviceType.IsAbstract || serviceType.IsInterface ? container.TryGetInstance(serviceType) : container.GetInstance(serviceType); } return container.GetInstance(serviceType, key); } public void Dispose() { if (CurrentNestedContainer != null) { CurrentNestedContainer.Dispose(); } Container.Dispose(); } public IEnumerable<object> GetServices(Type serviceType) { return DoGetAllInstances(serviceType); } public void DisposeNestedContainer() { if (CurrentNestedContainer != null) CurrentNestedContainer.Dispose(); } public void CreateNestedContainer() { if (CurrentNestedContainer != null) return; CurrentNestedContainer = Container.GetNestedContainer(); } } 

Then you can set the resolver like this:

 public class MvcApplication : System.Web.HttpApplication { public static StructureMapDependencyResolver StructureMapResolver { get; set; } protected void Application_Start() { ... // Setup your Container before var container = IoC.Initialize(); StructureMapResolver = new StructureMapDependencyResolver(container); DependencyResolver.SetResolver(StructureMapResolver); } protected void Application_BeginRequest(object sender, EventArgs e) { StructureMapResolver.CreateNestedContainer(); } protected void Application_EndRequest(object sender, EventArgs e) { StructureMapResolver.DisposeNestedContainer(); } } 

An excellent result of this type of configuration is to get a new child container for each request, and the container is deleted at the end of each request.

+3
source

I just tried this and its work, please let me if this is not the best way.

 StructuremapMvc.StructureMapDependencyScope.Container 
+1
source

There are two dependent converters for ASP.NET MVC and others for ASP.NET Web Api

Web Api: use WebApiContrib.IoC.StructureMap.StructureMapResolver

MVC: use StructureMapDependencyResolver

 public class StructureMapDependencyResolver : StructureMapDependencyScope, IDependencyResolver { public StructureMapDependencyResolver(IContainer container) : base(container) { } public IDependencyScope BeginScope() { var child = Container.GetNestedContainer(); return new StructureMapDependencyResolver(child); } } public class StructureMapDependencyScope : ServiceLocatorImplBase, IDependencyScope { protected readonly IContainer Container; public StructureMapDependencyScope(IContainer container) { if (container == null) { throw new ArgumentNullException(nameof(container)); } Container = container; } public void Dispose() { Container.Dispose(); } public override object GetService(Type serviceType) { if (serviceType == null) { return null; } return serviceType.IsAbstract || serviceType.IsInterface ? Container.TryGetInstance(serviceType) : Container.GetInstance(serviceType); } public IEnumerable<object> GetServices(Type serviceType) { return Container.GetAllInstances(serviceType).Cast<object>(); } protected override IEnumerable<object> DoGetAllInstances(Type serviceType) { return Container.GetAllInstances(serviceType).Cast<object>(); } protected override object DoGetInstance(Type serviceType, string key) { if (string.IsNullOrEmpty(key)) { return serviceType.IsAbstract || serviceType.IsInterface ? Container.TryGetInstance(serviceType) : Container.GetInstance(serviceType); } return Container.GetInstance(serviceType, key); } } 

Usage is as follows:

 public static class Ioc { public static void Config() { var container = InitializeContainer(); var webApiDependencyResolver = new StructureMapResolver(container); GlobalConfiguration.Configuration.DependencyResolver = webApiDependencyResolver; var mvcDependencyResolver = new StructureMapDependencyResolver(container); DependencyResolver.SetResolver(mvcDependencyResolver); } } public class WebApiApplication : System.Web.HttpApplication { protected void Application_Start() { Ioc.Config(); ... } } 
0
source

Source: https://habr.com/ru/post/1203594/


All Articles