2014-09-29 7 views
5

Używam Structuremap jako mojego Resolver zależności. Próbuję zaimplementować wzór kontenera na żądanie w moim pliku Global.asax.cs.Jak uzyskać instancję IContainer Structuremap z Asp.Net MVC 5 Resolver zależności

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


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

Jako ObjectFactory nie będą wspierane w przyszłych wersjach StructureMap Chciałbym uzyskać dostęp do pojemnika z DependencyResolver. Jak to możliwe?

Dzięki z góry.

Noufal

Odpowiedz

3

Po wpadł na to pytanie sobie, this was the best guide udało mi się znaleźć dla rejestracji StructureMap z ASP.NET MVC jest Dependency Resolver (przez CommonServiceLocator package).

Skopiowałem i wkleiłem wyżej wymienione rozwiązanie artykułu, ale polecam przechodzenie przez zalety tego rozwiązania w oryginalnym artykule.

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

Następnie można ustawić resolverowi tak:

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

Wielki wynikiem tego typu konfiguracja jest pojawić nowy pojemnik dziecko na żądanie, pojemnik jest usuwany na końcu każdego wniosku.

1

Po prostu próbowałem tego i działa, proszę pozwolić mi, jeśli to nie jest najlepszy sposób.

StructuremapMvc.StructureMapDependencyScope.Container 
0

Istnieją dwa przeliczniki jeden z zależnościami dla ASP.NET MVC i innych dla ASP.NET Web API

Api Web: Wykorzystanie WebApiContrib.IoC.StructureMap.StructureMapResolver

MVC : Użyj 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); 
    } 
} 

Sposób użycia jest następujący:

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(); 
     ... 
    } 
} 
Powiązane problemy