繁体   English   中英

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

[英]How to get the Structuremap IContainer instance from Asp.Net MVC 5 Dependency Resolver

我正在使用Structuremap作为依赖项解析器。 我正在尝试在Global.asax.cs文件上实现“每个请求的容器模式”。

    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中访问该容器。 怎么可能?

提前致谢。

努法

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

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

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

这种配置的好结果是,每个请求都会收到一个新的子容器,该容器将在每个请求结束时被丢弃。

我只是尝试过此方法及其工作方式,如果不是最佳方法,请让我使用。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM