우리는 설정 파일에 성의 윈저 구성 요소를 선언했습니다. 내부의 일부 구성 요소는 다른 구성 요소의 서비스를 필요로 할 수 있습니다.캐슬 구성품은 주문을 처리합니다.
문제는 응용 프로그램이 닫히고 컨테이너가 처리 중일 때입니다. 시작/삭제 가능한 구성 요소 (A)의 Dispose()/중지() 중에 다른 구성 요소 (B)의 서비스가 필요한 경우 ComponentNotFoundException가 발생합니다. 그때까지 B는 이미 컨테이너에서 제거됩니다.
app config 파일의 구성 요소 선언 순서가 중요하다는 것을 알고 있습니다. 그리고 reodering A와 B는 문제를 해결합니다.
구성 요소가 폐기되는 순서에 영향을주는 더 좋은 방법이 있습니까?
편집 :
class Program
{
static void Main()
{
IoC.Resolve<ICriticalService>().DoStuff();
IoC.Resolve<IEmailService>().SendEmail("Blah");
IoC.Clear();
}
}
internal class CriticalService : ICriticalService, IStartable
{
public void Start()
{}
public void Stop()
{
// Should throw ComponentNotFoundException, as EmailService is already disposed and removed from the container
IoC.Resolve<IEmailService>().SendEmail("Stopping");
}
public void DoStuff()
{}
}
internal class EmailService : IEmailService
{
public void SendEmail(string message)
{
Console.WriteLine(message);
}
public void Dispose()
{
Console.WriteLine("EmailService Disposed.");
GC.SuppressFinalize(this);
}
}
internal interface ICriticalService
{
void DoStuff();
}
internal interface IEmailService : IDisposable
{
void SendEmail(string message);
}
public static class IoC
{
private static readonly IWindsorContainer _container = new WindsorContainer(new XmlInterpreter());
static IoC()
{
_container.AddFacility<StartableFacility>();
// Swapping the following 2 lines resolves the problem
_container.AddComponent<ICriticalService, CriticalService>();
_container.AddComponent<IEmailService, EmailService>();
}
public static void Clear()
{
_container.Dispose();
}
public static T Resolve<T>()
{
return (T)_container[typeof(T)];
}
}
참고 : 어떻게 용기에 삽입하는 구성 요소의 순서를 교환 코드의 주석을 참조하십시오 여기 ComponentNotFoundException가 발생합니다 샘플 코드를 제공 주석의 요청에 따라 문제를 해결합니다.
Start/Stop은 StartableFacility에서 제공하는 두 가지 문제이며 Disposable은 원칙적으로 시작/중지와 관련이없는 또 다른 문제입니다. StartableFacility는 구성 요소를 "해제"할 때 실행되는 첫 번째 Stop 관심사를 보장합니다. Dispose()가 Stop() 전에 실행된다고 말하면 버그처럼 보입니다. 우리에게 몇 가지 코드를 보여줄 수 있습니까? 아마도 테스트 케이스를 게시 할 수 있습니까? –
귀하의 의견을 보내 주셔서 감사합니다. Container가 삭제되면 시작 가능한 각 구성 요소를 반복하고 각 Stop(), Dispose()를 호출하여 Container에서 제거합니다. 나는 그것이 모든 시작품에 대해 Stop()을 먼저 호출해야하며, 그 다음에 폐기하고 Container에서 제거해야한다고 예상 할 것이다. –
예, 컨테이너는 시작 가능한 각 구성 요소를 반복하고 각 Stop(), Dispose()를 호출합니다. 이는 동작입니다. ComponentNotFoundException을 throw하는 테스트 케이스를 게시 할 수 있습니까? –