DI 与 Castle Windsor 在 Windows Service 托管的 WCF 服务中
本文关键字:WCF 服务 Service Castle Windsor Windows DI | 更新日期: 2023-09-27 18:36:01
我正在尝试让Castle Windsor DI与作为Windows服务托管的WCF服务一起工作。我在这里采用了这种方法
WCF 服务库作为使用 Castle.Windsor 3.0 问题的 Windows 服务托管
但是,我遇到的问题是,如果我的服务实现类没有默认的无参数构造函数,ServiceHost 将不允许我在 OnStart() 中创建此实例。如果我提供无参数构造函数,服务控制台将使用该构造函数启动服务,因此我不会注入任何依赖项。
下面的代码
public class WindowsService : ServiceBase
{
public ServiceHost ServiceHost;
public WindowsService()
{
ServiceName = "CRMCustomerService";
}
public static void Main()
{
// Bootstrap the Castle Windsor DI setup
Run(CreateContainer().Resolve<ServiceBase>());
}
#region Service methods
protected override void OnStart(string[] args)
{
if (ServiceHost != null)
{
ServiceHost.Close();
}
ServiceHost = new ServiceHost(typeof(CustomerService));
ServiceHost.Open();
}
protected override void OnStop()
{
if (ServiceHost != null)
{
ServiceHost.Close();
ServiceHost = null;
}
}
#endregion
#region Private Methods
private static IWindsorContainer CreateContainer()
{
var container = new WindsorContainer();
container.Install(FromAssembly.This());
return container;
}
#endregion
}
[ServiceBehaviorAttribute(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Single)]
public class CustomerService : ICustomerService
{
private readonly IDataRepository _repository;
private readonly ILogger _logger;
public CustomerService(IDataRepository repository)
{
_repository = repository;
_logger = new RootLogger(Level.Error);
}
}
public class ServicesInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container
.AddFacility<WcfFacility>(f =>
{
f.CloseTimeout = TimeSpan.Zero;
})
.Register(
Component
.For<IDataRepository>()
.ImplementedBy<CustomerRepository>()
.LifeStyle.Transient
.AsWcfService(),
Component.For<ServiceBase>().ImplementedBy<WindowsService>());
}
}
谁能看出我做错了什么?我想在服务启动时以及在创建 WCF 服务的实例时引导 Windsors DI 容器,以便它在此时注入依赖项。
1)你应该有两个构造函数,正如另一张海报所建议的那样,一个 默认值和一个以依赖项作为参数的依赖项。
2)正如您在链接到的帖子中看到的那样,您应该使用城堡的WCF设施来 托管服务(请注意帖子中的AsWcfService
语法 链接到)。 您所要做的就是编写城堡代码,注册 您的所有服务依赖项和 Castle 将负责 休息。这几乎就像变魔术一样!
你可以有两个构造函数。其中无参数调用将依赖项作为参数的重载。
public WindowsService()
this(new ServiceHost());
public WindowsService(ServiceHost serviceHost)
{
this.ServiceHost = serviceHost;
}
您可以使用所需的构造函数实例化服务实现,并将其作为参数传递给服务主机,例如
var service = CustomerService(container.Resolve<IDataRepository>());
ServiceHost = new ServiceHost(service);
甚至像这样,如果您已正确配置容器:
var service = container.Resolve<ICustomerService>();
ServiceHost = new ServiceHost(service);
但是,在这种情况下,它将在单例模式下工作,我记得您需要将服务实现的 InstanceContextMode 更改为单