I want to resolve in Windsor a series of classes that implement this interface:
public interface IDocumentParser
{
Message ParseDocument(XDocument document);
IDocumentParser NextParser { get; set; }
}
Basically what I have is a chain of responsibility, in which the first parser delegates to the next in the chain if it can’t handle the document. I was wondering if there is a way in Windsor to solve this dependency. I tried the following, but it sets my NextParser property to null.
container.Register(
Component.For<IDocumentParser>().ImplementedBy<DocumentParser1>(),
Component.For<IDocumentParser>().ImplementedBy<DocumentParser2>(),
Component.For<IDocumentParser>().ImplementedBy<DocumentParser3>(),
Component.For<IDocumentParser>().ImplementedBy<DocumentParser4>());
Any suggestion?
EDIT:
Ok, it looks like the problem was the following: I had a dependent component registered as startable (via the StartableFacility), which got called before my parsers registration.
class DependentObject
{
public DependentObject(IDocumentParser firstParser) {}
public void Start() {}
public void Stop() {}
}
Now, it looks like a startable component gets started as soon as it is registered, thereby stopping in some way the resolution process for all the dependent parsers. For my case I solved by configuring the StartableFacility with a DeferredStart(), like this:
var container = new WindsorContainer();
container
.AddFacility<StartableFacility>(
// Without this container.Resolve<IDocumentParser>().NextParser is null
c => c.DeferredStart());
.Register(
Component.For<DependentObject>()
.StartUsingMethod(m => m.Start)
.StopUsingMethod(m => m.Stop),
Component.For<IDocumentParser>().ImplementedBy<DocumentParser1>(),
Component.For<IDocumentParser>().ImplementedBy<DocumentParser2>(),
Component.For<IDocumentParser>().ImplementedBy<DocumentParser3>(),
Component.For<IDocumentParser>().ImplementedBy<DocumentParser4>()
);
I am wondering, though, why this is happening. In such cases I expect Windsor either to throw an exception, stating that he is unable to solve the IDocumentParser dependency, or solving the whole chain, and not just the first node. Anybody knows if this is by design?
This is by design – Windsor by default treats property dependencies as optional so when one is requested it does its best to satisfy it, but if it can’t it just doesn’t.
If you want to force those dependencies to be satisfied either make them mandatory or use service overrides to specify them explicitly