1

내 구현 내 DbContextUnitOfWork이 내 서비스 계층에있는 다중 계층 응용 프로그램이 있습니다. 이 계층에는 System.Web에 대한 참조가 없습니다.SimpleInjector 서비스 범위의 요청 범위

함께 내 UI 레이어에서 내 확장을 사용하여 내 모든 주입을 초기화하는 내 CompositionRoot 클래스가 있습니다.

하지만 내 DbContextUnitOfWork는 요청 범위를 필요로하고, 나는 HttpContext 또는 WebRequestLifestyle에 대한 액세스 권한을 가지고 있지 않기 때문에, 아래의 예처럼이를 설정할 수 없습니다입니다.

요청 범위를 사용하려면이 RegisterEntityFramework(...) 확장자를 내 UI 레이어로 이동해야합니까? 아니면 내 서비스 레이어에서 System.Web을 참조해야합니까?

나는 의존성 주입을 처음 접했을 뿐이므로 최고의 시나리오가 그러한 시나리오에서 무엇인지에 대해 지나치게 편집증 적이기도합니다.

ServiceLayer/EntityFramework/CompositionRoot.cs

public static class CompositionRoot 
{ 
    public static void RegisterEntityFramework(this Container container) 
    { 
     var lifestyle = Lifestyle.CreateHybrid(
      lifestyleSelector:() => HttpContext.Current != null, // HttpContext not available 
      trueLifestyle: new WebRequestLifestyle(), 
      falseLifestyle: new LifetimeScopeLifestyle() 
     ); 

     var contextRegistration = lifestyle.CreateRegistration<EntityDbContext, EntityDbContext>(container); 
     container.AddRegistration(typeof(EntityDbContext), contextRegistration); 
     container.AddRegistration(typeof(IUnitOfWork), contextRegistration); 
    } 
} 

UILayer/App_Start/CompositionRoot.cs

public static class RootComposition 
{ 
    public static void Configure() 
    { 
     var container = new Container(); 
     container.RegisterEntityFramework(); // extension 

     container.RegisterMvcControllers(Assembly.GetExecutingAssembly()); 
     container.RegisterMvcAttributeFilterProvider(); 

     container.Verify(); 

     DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container)); 
     GlobalConfiguration.Configuration.DependencyResolver = new WebApiDependencyResolver(container); 
    } 
} 

답변

1

composition root는 응용 프로그램의 시작 경로의 일부이다. 귀하의 경우 귀하의 웹 응용 프로그램입니다. 시스템의 구성 루트 references all assemblies. 이 부분에서 비즈니스 계층 별 등록을 이동해야하는 유일한 이유는 비즈니스 계층이 여러 최종 애플리케이션 (MVC 애플리케이션과 WCF 웹 서비스 모두)에 의해 재사용되는 경우입니다. 당신이 당신의 웹 응용 프로그램에 모든 것을 이동하면

, 당신의 DbContext의 등록은 간단하다 : 여러 응용 프로그램을하고 비즈니스 계층의 등록 로직을 재사용해야하는 경우

var scopedLifestyle = new WebRequestLifestyle(); 
var contextRegistration = 
    scopedLifestyle.CreateRegistration<EntityDbContext, EntityDbContext>(container); 
container.AddRegistration(typeof(EntityDbContext), contextRegistration); 
container.AddRegistration(typeof(IUnitOfWork), contextRegistration); 

, 그렇지 정확히 어떤 라이프 스타일을 사용하는지 알고 있어야합니다. 이 경우 당신은 ScopedLifestyle와 비즈니스 계층 구성 루트를 제공 할 수 있습니다 다음과 같이

public static void RegisterEntityFramework(this Container container, 
    ScopedLifestyle lifestyle) 
{ 
    var contextRegistration = 
     lifestyle.CreateRegistration<EntityDbContext, EntityDbContext>(container); 
    container.AddRegistration(typeof(EntityDbContext), contextRegistration); 
    container.AddRegistration(typeof(IUnitOfWork), contextRegistration); 
} 

당신은 당신의 위해 Application_Start 내에서 이것을 호출 할 수 있습니다

당신은 왕이다
container.RegisterEntityFramework(new WebRequestLifestyle()); 
+1

,이 똑똑! – janhartmann

+0

부탁드립니다. 내 /App_Start/CompositionRoot.cs에 모든 것을 연결하고 비즈니스 계층에는 별도의 "모듈"이 없습니까? – janhartmann

+0

@meep : IMO 여러 개의 최종 응용 프로그램이있는 경우 비즈니스 계층에 '모듈'만 있어야합니다. – Steven