我正在尝试让 CaSTLe (3.0) 将构造函数参数注入(inject)到 WCF 服务中,就像这样
ServiceHostBase clientServiceHost = new Castle.Facilities.WcfIntegration.DefaultServiceHostFactory()
.CreateServiceHost(typeof(IClientExchange).AssemblyQualifiedName, new Uri[0]);
但是我收到以下异常“提供的服务类型无法作为服务加载,因为它没有默认(无参数)构造函数。”
ClientExchange 类型的服务实现采用 IProviders 类型的构造函数参数
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class ClientExchangeService : ExchangeService, IClientExchange
{
public ClientExchangeService(IProviders providers)
: base(providers) { }
}
我的温莎安装程序如下所示:
container.AddFacility<WcfFacility>()
.Register
(
Component.For<IProviders>().Instance(Providers.DbInstance),
Component.For<IClientExchange>().ImplementedBy<ClientExchangeService>(),
);
目前似乎 WCF 正在尝试在没有城堡提供依赖项的情况下更新服务。在那里尝试了一些替代示例,但许多示例适用于 caSTLe pre 3.0 的早期版本。我一定是在某处遗漏了一个钩子(Hook)?我如何告诉 WCF 将构造责任推迟到城堡?
请您参考如下方法:
我认为:how do i pass values to the constructor on my wcf service可能是您问题的答案。或者,对于更具体的温莎,这可能会有所帮助:Dependency Injection in WCF Using Castle Windsor .
更新
好的,所以我想我已经弄明白了。首先是这个属性的问题:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
如果您不指定 Windsor 将能够完美地将依赖项注入(inject)到构造函数中 - 但它不能。
通过查看该属性的描述 here我看到您希望您的服务是单例的,因为这是 Windsor 的默认设置,您可以简单地删除该属性,它应该开始为您工作并按照您的预期运行。
您可能对另外两种专门针对 WCF 的生活方式感兴趣:
- LifestylePerWcfOperation()
- LifestylePerWcfSession()
(在正常位置指定它们 - 更多信息可用 here )
顺便说一句,您根本不必执行 ServiceHostBase
操作,而是可以像这样使用 AsWcfService
扩展方法(我个人更喜欢这种方式):
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"))));