我使用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
答案 0 :(得分:3)
我自己遇到了这个问题,this was the best guide我可以找到用ASP.NET MVC的依赖性解析器注册StructureMap(通过CommonServiceLocator package)。
我已经复制并粘贴了上述文章的解决方案,但我建议您在原始文章中了解此解决方案的好处。
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();
}
}
然后您可以像这样设置解析器:
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();
}
}
这种配置的最佳结果是每个请求都会收到一个新的子容器,并在每个请求结束时处理容器。
答案 1 :(得分:1)
我只是尝试了这个和它的工作,请让我,如果它不是最好的方式。
StructuremapMvc.StructureMapDependencyScope.Container
答案 2 :(得分:1)
有两个依赖项解析器,一个用于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<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);
}
}
用法如下......
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();
...
}
}