如何从Asp.Net MVC 5依赖性解析器获取Structuremap IContainer实例

我使用Structuremap作为我的依赖关系解析器。 我试图在我的Global.asax.cs文件上实现Container Per Request Pattern。

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

由于在将来的Structuremap版本中不支持ObjectFactory,我希望从DependencyResolver访问容器。 怎么可能?

提前致谢。

Noufal

自己遇到这个问题后, 这是我用ASP.NET MVC的Dependency Resolver注册StructureMap 的最佳指南 (通过CommonServiceLocator包 )。

我复制并粘贴了上述文章的解决方案,但我建议在原始文章中介绍此解决方案的优点。

 public class StructureMapDependencyResolver : ServiceLocatorImplBase { private const string StructuremapNestedContainerKey = "Structuremap.Nested.Container"; public IContainer Container { get; set; } private HttpContextBase HttpContext { get { var ctx = Container.TryGetInstance(); 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 DoGetAllInstances(Type serviceType) { return (CurrentNestedContainer ?? Container).GetAllInstances(serviceType).Cast(); } 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 GetServices(Type serviceType) { return DoGetAllInstances(serviceType); } public void DisposeNestedContainer() { if (CurrentNestedContainer != null) CurrentNestedContainer.Dispose(); } public void CreateNestedContainer() { if (CurrentNestedContainer != null) return; CurrentNestedContainer = Container.GetNestedContainer(); } } 

然后你可以这样设置解析器:

 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(); } } 

这种配置的最佳结果是每个请求都会收到一个新的子容器,并在每个请求结束时处理容器。

我只是尝试了这个和它的工作,请让我,如果它不是最好的方式。

 StructuremapMvc.StructureMapDependencyScope.Container 

有两个依赖项解析器,一个用于ASP.NET MVC,另一个用于ASP.NET Web Api

Web Api:使用WebApiContrib.IoC.StructureMap.StructureMapResolver

MVC:使用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 GetServices(Type serviceType) { return Container.GetAllInstances(serviceType).Cast(); } protected override IEnumerable DoGetAllInstances(Type serviceType) { return Container.GetAllInstances(serviceType).Cast(); } 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); } } 

用法如下……

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