2014-11-04 4 views
0

MVC 응용 프로그램이 있고 Autofac을 사용하여 종속성을 해결하고 있습니다.Autofac 여러 컨테이너 등록

나는 2 개의 컨테이너를 만들고 상황에 따라 사용할 컨테이너를 결정해야하는 상황이 있습니다.

컨트롤러의 Home이 호출되면 container1을 사용해야하거나 그렇지 않으면 container2를 사용해야하는 경우입니다.

Application_Start는 컨테이너를 등록하는 곳입니다.

런타임시 발생시키는 방법을 잘 모르겠습니다. 어떤 도움을 주셔서 감사합니다. 응용 프로그램이 격리 된 여러 모듈로 구성되어있는 경우 다른 컨테이너에서 컨트롤러의 해결을 해줘서

+0

컨테이너간에 몇 개의 등록이 다른가요? 델리게이트 팩토리 또는 런타임시 인스턴스화를 변경하는 다른 방법이 더 유용 할 수 있습니다. – ESG

+0

일부 등록은 다양하며, tat을 수행하는 일부 코드 샘플을 통해 나를 도와 줄 수 있으면 좋을 것입니다. – user2388339

+0

Autofac 문서의 [Implementer 선택] (https://github.com/autofac/Autofac/wiki/Component-Creation) 섹션을 살펴 보시기 바랍니다. 특정 구현의 세부 사항을 묻는 것보다 우선 무엇을하려고하는지 더 잘 설명해야합니다. – ESG

답변

1

이유 중 하나

덕분이다. 이 경우 모듈이 서로 영향을주고 모듈 당 컨테이너를 갖는 것이 바람직하지 않을 수 있습니다. 그러나 거의 모든 다른 상황에서는 여러 컨테이너 인스턴스를 갖는 것이 타당하지 않습니다.

이렇게 필요한 경우 컨트롤러 유형에 따라 컨테이너를 전환 할 수있는 사용자 정의 IControllerFactory을 직접 만들어야합니다. 예를 들어, 이런 일이 또

internal sealed class MultiplContainerControllerFactory : IControllerFactory 
{ 
    public IController CreateController(RequestContext requestContext, string controllerName) 
    { 
     var factory = this.GetFactory(requestContext); 
     var controller = factory.CreateController(requestContext, controllerName); 

     // By storing the factory in the request items for this controller, 
     // we allow it to be easily retrieved 
     // during ReleaseController and delegate releasing to the correct controller. 
     HttpContext.Current.Items["ContrFct_" + controller.GetType().FullName] = factory; 

     return controller; 
    } 

    public SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, 
     string controllerName) 
    { 
     var factory = this.GetFactory(requestContext); 
     return factory.GetControllerSessionBehavior(requestContext, controllerName); 
    } 

    public void ReleaseController(IController controller) 
    { 
     var controllerFactory = (IControllerFactory)HttpContext.Current.Items["ContrFct_" + 
      controller.GetType().FullName]; 

     controllerFactory.ReleaseController(controller); 
    } 

    private IControllerFactory GetFactory(RequestContext context) 
    { 
     // return the module specific factory based on the requestcontext 
    } 
} 

, 당신은 용기 당 특별한 AutofacControllerFactory가 필요합니다. 그러면 다음과 같이 보일 수 있습니다.

public sealed class AutofacControllerFactory : DefaultControllerFactory 
{ 
    public readonly IContainer Container; 
    private readonly string moduleName; 

    public AutofacControllerFactory(IContainer container, string moduleName) 
    { 
     this.Container = container; 
     this.moduleName = moduleName; 
    } 

    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) 
    { 
     if (controllerType == null) 
     { 
      // The base method throws an expressive 404 HTTP error. 
      base.GetControllerInstance(requestContext, controllerType); 
     } 

     // We need to start a new lifetime scope when resolving a controller. 
     // NOTE: We can apply MatchingScopeLifetimeTags.RequestLifetimeScopeTag to the BeginLifetimeScope 
     // method and in this case we can use .InstancePerRequest(), but in that case it becomes impossible to 
     // verify the DI configuration in an integration test. 
     ILifetimeScope lifetimeScope = this.Container.BeginLifetimeScope(); 

     // We need to store this lifetime scope during the request to allow to retrieve it when the controller 
     // is released and to allow to dispose the scope. Memory leaks will be ensured if we don't do this. 
     HttpContext.Current.Items[controllerType.FullName + "_lifetimeScope"] = lifetimeScope; 

     // This call will throw an exception when we start making registrations with .InstancePerRequest, 
     // because the WebRequest functionality of Autofac is tied to the AutofacDependencyResolver, which we 
     // don't use here. We can't use the AutofacDependencyResolver here, since it stores the created lifetime 
     // scope in the HttpContext.Items, but it uses a fixed key, which means that if we resolve multiple 
     // controllers for different application modules, they will all reuse the same lifetime scope, while 
     // this scope originates from a single container. 
     try 
     { 
      return (IController)lifetimeScope.Resolve(controllerType); 
     } 
     catch (Exception ex) 
     { 
      lifetimeScope.Dispose(); 

      throw new InvalidOperationException("The container of module '" + this.moduleName + 
       "' failed to resolve controller " + controllerType.FullName + ". " + ex.Message, ex); 
     } 
    } 

    [DebuggerStepThrough] 
    public override void ReleaseController(IController controller) 
    { 
     try 
     { 
      base.ReleaseController(controller); 
     } 
     finally 
     { 
      var scope = (ILifetimeScope)HttpContext.Current 
       .Items[controller.GetType().FullName + "_lifetimeScope"]; 

      scope.Dispose(); 
     } 
    } 
} 
관련 문제