Castle 3.0 WCF Facility - don't allow parameters in service constructor

I am trying to have Castle (3.0) inject the params constructor into a WCF service like this

ServiceHostBase clientServiceHost = new Castle.Facilities.WcfIntegration.DefaultServiceHostFactory()
.CreateServiceHost(typeof(IClientExchange).AssemblyQualifiedName, new Uri[0]);

      

However, I get the following exception: "The provided service type cannot be loaded as a service because it does not have a default (no parameter) constructor.

A utility impl of type ClientExchange takes a constructor parameter of type IProviders

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class ClientExchangeService : ExchangeService, IClientExchange
{
    public ClientExchangeService(IProviders providers)
        : base(providers) { }
}

      

My windsor installer looks like this:

container.AddFacility<WcfFacility>()
.Register
(
  Component.For<IProviders>().Instance(Providers.DbInstance),
  Component.For<IClientExchange>().ImplementedBy<ClientExchangeService>(),
);

      

At the moment it seems like WCF is trying to update the service without a lock providing the dependency. Tried several alternative examples, but many of them refer to previous versions of the pre 3.0 lock. Should I be missing a hook somewhere? How can I tell WCF to defer building responsibility until the castle?

+3


source to share


1 answer


I think this: how to pass values ​​to a constructor in my wcf service might be the answer to your problem. Or, for anything more than Windsor specific, this might help: Injecting dependencies in WCF with Castle Windsor .

UPDATE

Ok, so I think I figured it out. First of all, the problem is with this attribute:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]

      

Unless you specify that Windsor will be able to inject dependencies into the constructor perfectly fine - with that it cannot.

From looking at the description of this attribute here I can see that you want your service to be a single, since this is the default for Windsor you can simply remove this attribute and it should start working for you and behave as you expect ...



There are two other lifestyles that might interest you, especially for WCF:

  • LifestylePerWcfOperation ()
  • LifestylePerWcfSession ()

(put them in the usual place - more information is available here )

By the way, you don't need to do things at all ServiceHostBase

, you can instead use an extension method AsWcfService

like so (personally I prefer this way of doing it):

container
    .AddFacility<WcfFacility>(f => f.CloseTimeout = TimeSpan.Zero)
    .Register(
        Component
            .For<IProviders>()
            .Instance(Providers.DbInstance),
        Component
            .For<IClientExchange>()
            .ImplementedBy<ClientExchangeService>()
            .AsWcfService(new DefaultServiceModel()
                .AddEndpoints(WcfEndpoint
                    .BoundTo(new BasicHttpBinding())
                    .At("http://localhost:8000/ClientExchangeService"))));

      

+4


source







All Articles