0

here과 같이 작업 단위/저장소 패턴을 구현했지만 autofac 및 생성자 주입도 사용하므로 UnitOfWork 및 DbContext (PsyProfContext) 클래스를 다음과 같이 등록했습니다.Autofac에 등록 된 객체를 올바르게 처리하는 방법

builder.Register(context => new PsyProfContext()).InstancePerHttpRequest(); 
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerHttpRequest(); 

모두 훌륭합니다!

한 가지 제외하고 나는 또한 enterprise library logging block을 사용하고 있으며 Entity Framework를 사용하여 데이터베이스에 로그 항목을 쓰는 CustomTraceListener를 구현했습니다. 내 컨트롤러는 다음과 같습니다

은 (그 순간에 난 그냥 모든 일이 (IOC의가, 로깅, 엔티티 프레임 워크)이 작동하는지 확인하기 위해 노력하기 때문에 비어) :

public class HomeController : Controller 
{ 
    private readonly UnitOfWork unitOfWork; 

    public HomeController(IUnitOfWork unitOfWork) 
    { 
     this.unitOfWork = (UnitOfWork) unitOfWork; 
    } 

    // 
    // GET: /Home/ 
    public ActionResult Index() 
    { 
     throw new HttpException(); 
     return View(); 
    } 

    protected override void Dispose(bool disposing) 
    { 
     unitOfWork.Dispose(); 
     base.Dispose(disposing); 
    } 
} 

를 그리고 쓰기 방법 CustomTraceListener 클래스에 대해 UnitOfWork를 해결하려고 시도했습니다.

DependencyResolver.Current.GetService<IUnitOfWork>() as UnitOfWork; 

하지만 이미 처리 된 인스턴스가 있습니다. 그래서 몇 가지 중단 점을 넣어 컨트롤러의 Dispose 메서드가 CustomTraceListener 클래스의 Write 메서드보다 먼저 호출되었으므로 결국에는 DbContext (PsyProfContext)를 직접 사용하는 것 이외의 다른 솔루션을 찾지 못했습니다.

하지만이 솔루션이 마음에 들지 않습니다. DbContext 개체에 직접 액세스하는 경우 UnitOfWork 및 Repository 패턴을 사용하는 것이 좋습니다. 경우에 따라 등록 된 객체를 수동으로 생성하면 프로젝트에서 DI를 사용하는 것이 무엇이겠습니까.

그래서 이런 상황을 어떻게 처리 할 것인가에 대한 여러분의 의견을 듣고 싶습니까? 현재 구현이 괜찮습니까? 아니면 틀린 것이므로 다른 것에 대해 생각해야합니다.

어떤 도움을 주시면 대단히 감사 드리며 어떤 아이디어라도 환영합니다!

+0

이것은 관련이 없지만 서비스를 전송하는 이유는 무엇입니까? 어쨌든 서비스가 해결되지 않은 이유는 아마도 당신이 해결하려고 할 때 HttpContext가 null이기 때문일 것입니다. – maxlego

+1

작업 단위 (UOW)에 로깅을 연결할 필요가있는 이유가 있습니까? 일반적으로, 작업 단위 (UOW)는 예외가 _ 생하거나 일부 유효성 검증 오류가 _ 견되었지만 _ 생할 때 로깅이 성공해야하는 경우 커 L 트되지 않습니다. 사실 로깅이 가장 가치있는 오류가 발생하는 경우가 종종 있습니다! –

+0

당신은 캐스팅에 대해 완전히 옳았습니다. 나는 이것에 관심을 기울이지 않았습니다. – Peace87

답변

4

몇 가지 문제가있는 것 같습니다.

첫 번째로 컨트롤러에 작업 단위 오브젝트를 수동으로 배치하는 경우 컨트롤러는 생성자에서 Owned<IUnitOfWork>을 가져야합니다. 요청 수명이 처리되면 수명이 다할 때까지 소유권을 넘겨 받겠다 고 명시하지 않는 한 컨트롤러와 확인 된 종속성을 포함하여 IDisposable 구성 요소가 자동으로 삭제됩니다.

또는, 당신은 할 수 -

public class HomeController : Controller 
{ 
    Owned<IUnitOfWork> _uow; 
    public HomeController(Owned<IUnitOfWork> uow) 
    { 
    this._uow = uow; 
    } 
    protected override void Dispose(bool disposing) 
    { 
    if(disposing) 
    { 
     this._uow.Dispose(); 
    } 
    base.Dispose(disposing); 
    } 
} 

You can do that by using Owned<T>.는 (. 당신이 그렇게 당신이하지 두가 폐기 작업 당신의 단위를 할 disposing의 값을 점검 할 필요가있다 재정의 폐기에있는 작은 로직 수정을 참고)

builder 
    .RegisterType<UnitOfWork>() 
    .As<IUnitOfWork>() 
    .ExternallyOwned() 
    .InstancePerHttpRequest(); 

ExternallyOwned처럼 ExternallyOwned로 작업하여 단위를 등록하면 당신이 처리를 제어 할 수 있습니다 그 Autofac을 알려줍니다. 이 경우 컨트롤러가 이미있는 것처럼 보입니다. (일반적으로 나는 Autofac이 일을하고, 피할 수 있다면 소유권을 갖지 못하게하고 싶다.방식 사물을 보는 사실)

, 당신은 Autofac을하자 당신에 대한 처분을 할 경우 모두 폐기 문제를 방지 할 수있을 것, 설정되어 - DependencyResolver에 대한 호출은 작업 단위를 반환하는 아직 처리되지 않았고 괜찮습니다.

문제가 해결되지 않으면 ... 질문에 세부 정보를 추가 할 수 있습니다. 컨트롤러가 작업 단위 (UOW) 클래스를 사용하고있는 곳을 볼 수는 있지만 어디에서 로그를 기록하는지 알지 못하며, 작업 단위 (UOW)를 사용하는 리스너 구현에서 아무것도 볼 수 없습니다. 귀하의 질문의 첫 번째 주석에 언급 한 바와 같이

은 (또한, 컨트롤러의 생성자에서 당신은 IUnitOfWorkUnitOfWork까지 서비스를 캐스팅하지 않아야 - 그 인터페이스가 처음에 제공 한 추상화를 깨고.)

+0

Autofac이 IDisposable 구성 요소를 자동으로 제거하도록하는 것이 옳습니다. 나는이 기능에 대해 몰랐다. 그래서 나는 확실히 Autofac wiki를 읽어야한다. – Peace87

관련 문제