本文介绍了如何从Asp.Net MVC 5依赖项解析器获取Structuremap IContainer实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-06 01:19