Castle 3.0 WCF Facility - Not resolving paramters in service constructor

末鹿安然 提交于 2020-01-14 16:33:49

问题


I'm trying to have Castle (3.0) inject constructor params 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 service type provided could not be loaded as a service because it does not have a default (parameter-less) constructor.'

The service impl of type ClientExchange takes a constructor param 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 new up the service without castle providing the dependency. Tried a few alternative examples out there but many are for previous versions of castle pre 3.0. I must be missing a hook somewhere? How do I tell WCF to defer construction responsibility to castle?


回答1:


I think this: how do i pass values to the constructor on my wcf service might be the answer to your problem. Or, for something more Windsor specific this might help: Dependency Injection in WCF Using Castle Windsor.

UPDATE

OK, so I think I have figured this out. First of all the problem is this attribute:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]

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

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

There are two other lifestyles that you may be interested in that are specifically for WCF:

  • LifestylePerWcfOperation()
  • LifestylePerWcfSession()

(specify them in the normal place - more information is available here)

Incidentally, you do not have to do the ServiceHostBase stuff at all, instead you can use the AsWcfService extension method 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"))));


来源:https://stackoverflow.com/questions/9687520/castle-3-0-wcf-facility-not-resolving-paramters-in-service-constructor

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!