We have a number of castle windsor components declared in a config file. Some of the components somewhere deep inside might require the services of other components.
The problem is when the application is being closed and the Container is being disposed. During Dispose()/Stop() of the Startable/Disposable component (A) when it requires the services of some other component (B) ComponentNotFoundException then raised. By that time B is already removed from the container.
I've noticed that the order of components declarations in app config file is important. And reodering A and B solves the problem.
Is there a better way to influence the order in which the components are disposed?
Edited: Following a request in comments I provide here a sample code that will throw ComponentNotFoundException:
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)];
}
}
Note: See a comment in the code how swapping the order of inserting components in the container solves the problem.