2017-03-13 6 views
0

내 컨텍스트가 처리되는 방법에 대해 궁금하거나 처리가 전혀 필요하지 않습니다. 가비지 컬렉터가 모든 것을 깨끗하게 정리할 수 있다는 것을 알고 있지만, 내 마음의 뒷부분에 잔소리하는 것이 있습니다.의존성 주입은 내 DB 연결을 처리하는 것입니까?

은 내가 conext가

Questsion, 내 코드 DB 연결이 열려 떠나 단위 테스트를 위해 주입이 필요합니다.

내 서비스는 컨텍스트가 생성자로 전달되는 방식으로 다음과 같이 표시됩니다. 종속성 주입은 autofac에서 처리합니다.

public class FooService : IFooService 
{ 
    private readonly Context context; 

    public CountryService(Context context) 
    { 
      this.context = context; 
    } 

    public IEnumerable<Foo> GetAll() 
    { 
     return context.Foo.ToList(); 
    } 
} 

내 Autofac 내가으로 IDisposable이

public class FooService : IFooService , IDisposable 
{ 
    private readonly Context context; 

    public CountryService(Context context) 
    { 
     this.context = context; 
    } 

    public IEnumerable<Foo> GetAll() 
    { 
     return context.Foo.ToList(); 
    } 

    private bool disposed = false; 

    protected virtual void Dispose(bool disposing) 
    { 
     if (!this.disposed) 
     { 
      if (disposing) 
      { 
       context.Dispose(); 
      } 
     } 
     this.disposed = true; 
    } 

    public void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 
} 
+0

[문서를 읽었습니까?] (http://autofac.readthedocs.io/en/latest/lifetime/disposal.html) –

답변

0

문맥과 서비스의 수명을 혼합주의 추가 솔루션을 본 적이이

public class ServiceModule : Module 
{ 
    protected override void Load(ContainerBuilder builder) 
    { 
     // "ThisAssembly" means "any types in the same assembly as the module" 
     builder 
      .RegisterAssemblyTypes(ThisAssembly) 
      .Where(t => t.Name.EndsWith("Service")) 
      .WithParameter("context", new MyContext()) 
      .AsImplementedInterfaces(); 
    } 
} 

같은 외모를 설정합니다. 서비스는 싱글 톤과 같지만 컨텍스트는 요청 당 이상이어야합니다. 여러 스레드가 동일한 컨텍스트 개체에 액세스하여 연결 상태 오류가 발생할 수도 있습니다.

코드에서 autofac 컨테이너가 삭제되면 컨텍스트가 삭제됩니다.

당신은 몇 가지 상황에 맞는 공장을 만들거나 블록을 사용하여 컨텍스트를 직접 사용해야합니다 : 그것은 (DI-ED) 주입 것 같이 수동으로 Context 폐기해서는 안

public class FooService : IFooService 
{ 
    public CountryService() 
    { 
    } 

    public IEnumerable<Foo> GetAll() 
    { 
     using (var context = new Context()) 
     { 
      return context.Foo.ToList(); 
     } 
    } 
} 
+0

아, 내 게시물을 업데이트하려면 단위 테스트를 위해 콘텍스트를 주입해야합니다. . –

+0

코드에서 동일한 인스턴스를 매개 변수로 사용하고 있습니다. 문맥을 별도의 객체'builder.RegisterType ();'으로 등록 할 수 있으며'WithParameter' 정의를 사용할 필요가 없습니다. – Zapo

0

1), 그리고 기술적으로이다 아니 당신의 클래스의 인스턴스에 의해 소유, 즉 Autofac 그것의 처분을 동시에 관리 할 수있는 다른 장소로, 그리고 모든 이들의 수명에 따라 달라집니다 (즉, Autofac 실제로 알고있는 유일한 때 그것을 처리하는 것이 가장 좋습니다).

2) Autofac에는 범위, 수명을 사용하여 자동 처리가 있습니다. 귀하의 경우, 그것은 귀하의 컨테이너, 루트 범위를 의미하며, 범위가 벗어나면 모든 것이 폐기 될 것입니다. 그래서 걱정할 필요가 없습니다.
즉, Autofac 정렬은 개체의 수명과 처리를 관리하기위한 대체 메커니즘을 제공합니다. 그리고 실제로는 매우 깔끔하고 실제로 물건이 조직적으로 폐기 될 것이라는 확신을 가질 수 있습니다. 단위와

... 나는 일반적으로 필요하지 뭘하려는 테스트하지만, 나에게 일을 더 제어 할 수 있습니다 당신이 DI-ED 서비스의 수명보다 효율적으로 제어 할 수하고자하는 경우

// within your unit test 
using (var scope = Container.BeginLifetimeScope()) 
{ 
    // and now resolve your services using the 'scope' (instead of the Container) 
} 

3) 그들 자신을 처분하십시오. Owned<> 예를 들어 사용할 수 있습니다. .ctor 입력 매개 변수로 Owned<Context>을 사용하면 자동으로 삭제되지 않으므로 맞춤 방식으로 처리 할 수 ​​있습니다.