2014-09-29 23 views
5

我正在使用Structuremap作爲我的依賴關係解析器。我正在嘗試在Global.asax.cs文件上實現Container Per Request Pattern。如何從Asp.Net MVC 5獲得Structuremap IContainer實例依賴關係解析器

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


    public void Application_BeginRequest() 
    { 
     Container = ObjectFactory.Container.GetNestedContainer(); 
    } 

由於的ObjectFactory不會Structuremap的未來版本的支持,我想可以訪問來自DependencyResolver容器。怎麼可能?

在此先感謝。

Noufal

回答

3

已經遇到了這個問題,我自己,this was the best guide我能找到的(通過CommonServiceLocator package)與ASP.NET MVC的依賴解析器註冊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(); 
    }  
} 

這種類型的配置的偉大的結果是,你收到一個新的子容器每個請求,與容器在端部設置成的的每個請求。

1

我剛試過這個,它的工作,請讓我,如果它不是最好的方式。

StructuremapMvc.StructureMapDependencyScope.Container 
0

有兩個依賴解析器一個ASP.NET MVC和其他用於ASP.NET網頁API

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