问题描述
我正在使用Structuremap作为我的依赖项解析器.我正在尝试在Global.asax.cs文件上实现每个请求的容器模式".
I am using Structuremap as my Dependency Resolver. I am trying to implement Container Per Request Pattern on my 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();
}
由于在将来的Structuremap版本中将不支持ObjectFactory,所以我想从DependencyResolver中访问该容器.怎么可能?
As the ObjectFactory will not be supported in the future versions of Structuremap I would like get access to the container from the DependencyResolver. How is possible?
预先感谢.
努法尔
推荐答案
我自己也遇到了这个问题,这是最好的指南,我可以找到通过ASP.NET MVC的依赖项解析器注册StructureMap的方法(通过 CommonServiceLocator程序包).
Having ran into this question myself, this was the best guide I could find for registering StructureMap with ASP.NET MVC's Dependency Resolver (via the CommonServiceLocator package).
我已经复制并粘贴了上述文章的解决方案,但是我建议在原始文章中介绍该解决方案的优点.
I've copied and pasted the aforementioned article's solution, but I would recommend going through the benefits 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();
}
}
然后可以像这样设置解析器:
You can then set the resolver like so:
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();
}
}
这种配置的好结果是,您将在每个请求中收到一个新的子容器,该容器将在每个请求结束时丢弃.
The great result of this type of configuration is you receive a new child container per request, with the container being disposed of at the end of each request.
这篇关于如何从Asp.Net MVC 5依赖项解析器获取Structuremap IContainer实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!