문제

Windsor 컨테이너에 등록된 IDisposable을 구현하는 개체가 있는데 이를 처리하여 Dispose 메서드가 호출되고 다음에 Resolve가 호출되면 새 인스턴스를 가져오도록 하고 싶습니다.

하다

container.Release(obj); 

자동으로 Dispose()를 즉시 호출하시겠습니까?아니면 내가해야합니까?

obj.Dispose();
container.Release(obj);

릴리스가 정확히 무엇을 하는지에 대한 문서에서 아무것도 찾을 수 없습니다.

편집하다:내가 실행한 테스트 결과는 아래 답변을 참조하세요.이제 문제는 컨테이너가 싱글톤 라이프사이클을 가진 구성 요소의 인스턴스를 강제로 릴리스하도록 하려면 어떻게 해야 합니까?이 작업은 한 곳에서만 수행하면 되며 사용자 정의 수명 주기를 작성하는 것은 너무 무거운 것 같습니다. 이를 수행하는 방법이 내장되어 있지 않습니까?

도움이 되었습니까?

해결책

이것은 Windsor 컨테이너로 작업할 때 사람들이 실제로 인식하지 못하는 것이라고 생각합니다. 특히 자주 사용하는 경우는 다음과 같습니다. 놀라운 문서화되어 있지만 일회용 임시 구성 요소를 직접 릴리스하지 않는 한 커널이 폐기될 때까지 커널 수명 동안 컨테이너에 의해 유지되는 동작을 살펴보세요. 여기 - 빨리 인용하자면:

마이크로 커널에는 구성 요소를 처리하기 위해 일부 라우팅을 연결하고 구현할 수있는 플러그 가능한 릴리스 정책이 있습니다.MicroKernel에는 세 가지 IReleasePolicy 구현이 함께 제공됩니다.

  • 모든구성요소릴리스정책:MicroKernel 인스턴스 폐기 시 올바른 폐기를 시행하기 위해 모든 구성 요소를 추적합니다.
  • LifecycledComponentsReleasePolicy:관련 폐기 수명주기가 있는 구성요소만 추적합니다.
  • NoTrackingRelease정책:어떠한 추적도 수행하지 않습니다

IReleasePolicy 인터페이스를 사용하여 자체 릴리스 정책을 구현할 수도 있습니다.

더 쉽게 찾을 수 있는 방법은 정책을 다음으로 변경하는 것입니다. NoTrackingRelease정책 그런 다음 직접 폐기를 처리합니다. 이는 잠재적으로 위험할 수도 있지만 라이프스타일이 대체로 일시적인 경우(또는 컨테이너가 폐기될 때 애플리케이션이 곧 닫힐 경우) 아마도 큰 문제는 아닐 것입니다.그러나 이미 싱글톤에 주입된 모든 구성 요소는 참조를 보유하므로 싱글톤을 "새로 고침"하려고 할 때 문제가 발생할 수 있다는 점을 기억하십시오. 이는 나쁜 습관처럼 보이며 아마도 이를 피할 수 있는지 궁금합니다. 먼저 애플리케이션을 구성하는 방식을 개선하여 이를 수행하세요.

다른 접근 방식은 자체 폐기 구현을 사용하여 사용자 지정 수명 주기를 구축하는 것입니다(따라서 싱글톤을 릴리스하면 임시 수명 주기와 마찬가지로 실제로 구성 요소가 폐기됩니다).

또는 또 다른 접근 방식은 서비스에 대한 데코레이터를 싱글톤 라이프스타일로 컨테이너에 등록하고 실제 기본 서비스는 임시 라이프스타일로 컨테이너에 등록하는 것입니다. 그러면 구성 요소를 새로 고쳐야 할 때 임시 기본 구성 요소를 삭제하기만 하면 됩니다. 데코레이터를 사용하여 새로 해결된 인스턴스로 교체합니다(데코레이터를 가져오지 않으려면 서비스가 아닌 구성 요소 키를 사용하여 해결). 이렇게 하면 다른 싱글톤 서비스("새로 고침"되지 않음)의 문제가 보류되는 것을 방지할 수 있습니다. 폐기되어 사용할 수 없게 되었지만 약간의 캐스팅 등이 필요한 오래된 서비스에 적용합니다.작동하도록 합니다.

다른 팁

이는 컨테이너에 추가할 때 지정한 구성 요소의 라이프스타일에 따라 다릅니다.

라이프스타일이 Pooled인 경우 Release()를 사용합니다.이렇게 하면 다음 검색을 위해 구성 요소가 다시 풀에 저장됩니다(객체는 파괴되지 않으므로 폐기하는 것이 좋지 않습니다).

라이프스타일이 일시적인 경우 구성 요소를 가져올 때 새 객체가 생성됩니다.이 경우 폐기는 귀하에게 달려 있으며 릴리스에 전화할 필요가 없습니다.

라이프스타일이 Thread인 경우 각 스레드에 동일한 구성 요소가 사용되며 삭제되지 않습니다.

라이프스타일이 싱글톤인 경우 하나의 구성 요소만 생성되고 삭제되지 않습니다.

아마도 임시 구성 요소를 사용하고 있습니까?(적시에 처분하는 것에 대해 걱정하는 경우)이 경우 사용하여 사용하여 설정하면 설정 (또는 어딘가에 자신을 호출하십시오).

using(ISomeService service = container.Resolve<ISomeService>())
{
 // Do stuff here
 // service.Dispose is automatically called 
}

편집하다 - 예, 싱글톤을 "새로 고침"하거나 폐기하고 다시 생성하려면 컨테이너를 삭제하거나 사용자 정의 수명 주기를 작성해야 합니다.사용자 정의 수명 주기를 수행하는 것은 실제로 그렇게 어렵지 않으며 이를 수행하기 위한 논리를 한곳에 유지합니다.

좋아요, 그래서 테스트를 해봤는데 그런 것 같아요. Container.Release() 암시적으로 IDisposable의 원인이 됩니다. Dispose() 라이프스타일이 일시적인 경우에만 실행하는 방법입니다(정확히 정확하지는 않지만 요점은 라이프스타일이 싱글톤인 경우에는 별 일을 하지 않는다는 것입니다).

이제 전화하면 Container.Dispose() 삭제 가능한 메서드도 호출하지만 불행하게도 전체 커널이 삭제되므로 모든 구성 요소를 다시 추가해야 합니다.

var container = new WindsorContainer();
container.AddComponentWithLifestyle<MyDisposable>(Castle.Core.LifestyleType.Singleton);
var obj = container.Resolve<MyDisposable>();  // Create a new instance of MyDisposable
obj.DoSomething();
var obj2 = container.Resolve<MyDisposable>();  // Returns the same instance as obj
obj2.DoSomething();
container.Dispose();  // Will call the Disposable method of obj
// Now the components need to be added back in   
 container.AddComponentWithLifestyle<MyDisposable>(Castle.Core.LifestyleType.Singleton);
var obj3 = container.Resolve<MyDisposable>();  // Create a new instance of MyDisposable

다행히 내 경우에는 모든 구성 요소를 삭제해도 상당히 쉽게 복원할 수 있습니다.그러나 이것은 차선책입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top