Sneak view at Castle's WCF Facility by Mark Seemann
One of Castle Windsor's facilities addresses wiring up of WCF services. So far, the sparse documentation for the WCF Facility seems to indicate that you have to configure your container in a global.asax. That's not much to my liking. First of all, it reeks of ASP.NET, and secondly, it's not going to work if you expose WCF over protocols other than HTTP.
However, now that we know that a custom ServiceHostFactory is effectively a Singleton, a much better alternative is to derive from the WCF Facility's DefaultServiceHost class:
public class FooServiceHostFactory : DefaultServiceHostFactory { public FooServiceHostFactory() : base(FooServiceHostFactory.CreateKernel()) { } private static IKernel CreateKernel() { var container = new WindsorContainer(); container.AddFacility<WcfFacility>(); container.Register(Component .For<FooService>() .LifeStyle.Transient); container.Register(Component .For<IBar>() .ImplementedBy<Bar>()); return container.Kernel; } }
Although it feels a little odd to create a container and then not really use it, but only its Kernel property, this works like a charm. It correctly wires up this FooService:
public class FooService : IFooService { private readonly IBar bar; public FooService(IBar bar) { if (bar == null) { throw new ArgumentNullException("bar"); } this.bar = bar; } #region IFooService Members public string Foo() { return this.bar.Baz; } #endregion }
However, instead of the static CreateKernel method that creates the IKernel instance, I suggest that the WCF Facility utilizes the Factory Method pattern. As the WCF Facility has not yet been released, perhaps there's still time for that change.
In any case, the WCF Facility saves you from writing a lot of infrastructure code if you would like to wire your WCF services with Castle Windsor.
Comments
<installers>
<install assembly="Ploeh.AssemblyContainingWindsorInstallers"/>
</ installers>
See http://stw.castleproject.org/Windsor.Registering-Installers.ashx
Alternatively you could override protected IWindsorInstaller GetInstallers(); method and configure the container entirely in code.
Thoughts?
For the edge cases where adding an Installer isn't enough, I'd still prefer a Factory Method hook in DefaultServiceHostFactory, but being able to specify an Installer in web.config will likely address 90 percent (or more) of scenarios.
Looks good!
If you use Facility's default SH Factory it will look into your web.config for informations about how to configure itself.
ALternativelty you can provide your own subclass of the SH Factory, override its protected IWindsorInstaller[] GetInstallers(); method and then you'll be able to configure the container without using config file.
Don't get me wrong on the Factory Method thing. I don't expect to need it often (if at all), but I just think it would be a good OCP thing to do... Off the top of my head, I can't remember whether there are things you can do to a container that you can't do from an Installer. Maybe there aren't...
I do intend to leave the door open with factory method for people who can't use xml even if it's so minimal (or feel sick when even thinking about xml), but as you said - there really isn't anything you couldn't do from installer so I imagine it would be for emergency cases only.