2016-06-28 3 views
0

.NET의 API 컨트롤러 프로젝트에서 사용하고있는 서비스, 예를 들어 SomeService은 한 번만 초기화해야합니다 (요청 또는 SomeService 인스턴스가 아님). (관련이 있다고 생각하지 않지만 여기서는 이 초기화 부분 :.. 그것은 SomeService의 모든 인스턴스에 대해 이렇게하는 것은 이제 Global.asax에Autofac - DependencyResolver.Current.GetService <>()에서 생성 된 InstancePerRequest - 언제 출시됩니까?

new SomeService().Init(); 

에 unnecessarely 비용이 많이 드는 따라서 거기에 다음 줄 API가 생성되면위한 푸른 저장의 일부 설정입니다 않습니다, 나는 종속성 주입에 Autofac을 사용하고 SomeServiceISomeService으로, InstancePerRequest으로 등록합니다 (SomeService은 스레드로부터 안전하지 않으므로). 이제 SomeSer을 초기화하려고합니다. 컨테이너의 인스턴스를 통해 Global.asax의 vice. 내가이 오류를

An exception of type 'Autofac.Core.DependencyResolutionException' occurred in Autofac.dll but was not handled in user code 

Additional information: No scope with a Tag matching 'AutofacWebRequest' is visible from the scope in which the instance was requested. This generally indicates that a component registered as per-HTTP request is being requested by a SingleInstance() component (or a similar scenario.) Under the web integration always request dependencies from the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime, never from the container itself. 

을 제공

container.Resolve<ISomeService>().Init(); 

에로 컨테이너에서 인스턴스를 얻을하려고하면 오류 설명에 제안 그러나 따라서 Global.asax에에서 나는 인스턴스를 얻을.

DependencyResolver.Current.GetService<ISomeService>().Init(); 

는 내가 알고 싶은 것은 내가 Current에서 얻을 SomeService 인스턴스가 해제되거나되지 않는 것입니다? 실제 요청이 없으므로 확실하지 않습니다. 최악의 경우 new으로 콘크리트에서 인스턴스를 가져올 수 있습니다.

답변

1

두 책임을 Single Responsibility Principle을 손상시키는 하나의 구성 요소로 병합하려고합니다.

문제를 해결하려면 하늘색 저장소 (예 : IStorageProvider)를 초기화하는 구성 요소와 작업을 수행하는 다른 구성 요소로 구성 요소를 분할 할 수 있습니다. IStorageProviderSingleInstance으로 선언되며 필요한 경우 IStartable을 구현합니다. 다른 구성 요소는이 구성 요소를 사용합니다.

public class AzureStorageProvider : IStorageProvider, IStartable 
{ 
    public void Start() 
    { 
     // initialize storage 
     this._storage = new ... 
    } 
} 


public class SomeService : ISomeService 
{ 
    public SomeService(IStorageProvider storageProvider) 
    { 
     this._storageProvider = storageProvider; 
    } 

    private readonly IStorageProvider _storageProvider; 

    public void Do() 
    { 
     // do things with storage 
     this._storageProvider.Storage.ExecuteX(); 
    } 
} 

및 등록 :

builder.RegisterType<AzureStorageProvider>().As<IStorageProvider>().SingleInstance(); 
builder.RegisterType<SomeService>().As<ISomeService>().InstancePerRequest(); 

당신은 또한 IStorage을 등록하고 SomeService는 IStorage에 직접 달려 보자 공장으로 IStorageProvider를 사용할 수 있습니다.

builder.Register(c => c.Resolve<IStorageProvider>().Storage).As<IStorage>(); 
+0

몇 가지 좋은 점이 있습니다. IStartable은 좋은 해결책 인 것처럼 보이지만 특정 컨테이너 (예 : IStartable)와 관련된 항목을 서비스가 포함 된 dll에 추가하고 싶지는 않습니다. 일부는 Autofac을 사용할 수 있고, 다른 일부는 다른 것을 사용할 수 있습니다. 또한 초기화를 위해 또 다른 서비스를 빌드하고 싱글 톤으로 등록하는 경우 인스턴스도 해제되지 않습니다. 이 책에 더 많은 것, 나는 동의한다. 그러나 실제로는 아무것도 변경되지 않습니다. 내가 맞습니까? –

+0

이니셜 라이저를 싱글 톤으로 등록하면 응용 프로그램이 중지 될 때 인스턴스가 삭제됩니다. 그러나 당신이 그것을 처분 할 필요가 없기 때문에 그것이 진짜 문제라고 생각하지 않습니다, 이해합니다. 당신은'SomeService'를 처분 할 필요가 있습니다. –