I've a project with several WCF services inside of a .dll. Project uses Castle Windsor. There is also an SecurityServiceBehavior implements IServiceBehavior that WCF services should use. The SecurityServiceBehavior constructor needs the ISecuritySettingsProvider passed as argument. How it works without Windsor:
public class Service1Factory : ServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
var host = base.CreateServiceHost(serviceType, baseAddresses);
ISettingsProvider settingsProvider = new Service1SettingsProvider();
host.Description.Behaviors.Add(new SecurityServiceBehavior(settingsProvider));
return host;
}
}
public class Service2Factory : ServiceHostFactory
{
//the same but uses Service2SettingsProvider instead of Service1SettingsProvider
Then I can use this factories in .svc file. Now, how I'm registering this using Windsor:
Container.AddFacility<WcfFacility>();
Container.RegisterTransient<IServiceBehavior, SecurityServiceBehavior>();
Container.Register(Component.For<IService1>().
ImplementedBy<Service1>().LifeStyle.PerWcfSession());
Container.Register(Component.For<IService2>().
ImplementedBy<Service2>().LifeStyle.PerWcfSession());
//Need somehow fix this lines:
Container.Register(Component.For<ISecuritySettingsProvider>()
.ImplementedBy<Service1SettingsProvider>().LifestyleSingleton());
Container.Register(Component.For<ISecuritySettingsProvider>()
.ImplementedBy<Service2SettingsProvider>().LifestyleSingleton());
But it won't work the way I need cos I need SecurityServiceBehavior Service1SettingsProvider for Service1 and Service2SettingsProvider for Service2. What is the best way to do that?
Since there is no answer, I'll post solution I've finally used. Probably it could be also done via SubResolvers, but I haven't found a way to understand which service settings should belongs to. Instead of that, I've changed Service1Factory to derive Windsor's DefaultServiceHostFactory like this:
public class Service1Factory : DefaultServiceHostFactory
{
public Service1Factory()
: base(Service1Factory.CreateKernel())
{
}
private static IKernel CreateKernel()
{
var Container = AppContext.Container; // application container
var serviceContainer = new WindsorContainer();
serviceContainer.AddFacility<WcfFacility>();
serviceContainer.Register(Component.For<IService1>().ImplementedBy<Service1>().LifestyleTransient());
serviceContainer.Register(Component.For<IServiceBehavior>().ImplementedBy<SecurityServiceBehavior>().LifestyleTransient());
serviceContainer.Register(Component.For<ISecuritySettingsProvider>()
.ImplementedBy<Service1SettingsProvider>().LifestyleSingleton());
Container.AddChildContainer(serviceContainer);
return serviceContainer.Kernel;
}
}
By deriving DefaultServiceHostFactory and using CreateKernel() method I've provided Service1 it's unique container that Windsor also used to resolve IServiceBehavior. But I need app Container as well, so I've used Windsor's child container. Service2Factory is declared similar but uses Service2 and Service2SettingsProvider.