C# 在Windows服务托管的WCF服务中使用Castle Windsor的DI

C# 在Windows服务托管的WCF服务中使用Castle Windsor的DI,c#,wcf,castle-windsor,C#,Wcf,Castle Windsor,我正在尝试让Castle Windsor DI使用作为Windows服务托管的WCF服务。我在这里赞同这种做法 但是,我的问题是,如果我的服务实现类没有默认的无参数构造函数,ServiceHost将不允许我在OnStart()中创建此类的实例。如果我提供了一个无参数构造函数,那么服务控制台将使用该构造函数启动服务,因此我不会注入任何依赖项 代码如下 public class WindowsService : ServiceBase { public ServiceHos

我正在尝试让Castle Windsor DI使用作为Windows服务托管的WCF服务。我在这里赞同这种做法

但是,我的问题是,如果我的服务实现类没有默认的无参数构造函数,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>());
        }
    }
公共类WindowsService:ServiceBase
{
公共服务主机服务主机;
公共服务
{
ServiceName=“CRMCustomerService”;
}
公共静态void Main()
{
//引导城堡温莎DI设置
运行(CreateContainer().Resolve());
}
#区域服务方法
启动时受保护的覆盖无效(字符串[]args)
{
如果(ServiceHost!=null)
{
ServiceHost.Close();
}
ServiceHost=新的ServiceHost(typeof(CustomerService));
Open();
}
受保护的覆盖void OnStop()
{
如果(ServiceHost!=null)
{
ServiceHost.Close();
ServiceHost=null;
}
}
#端区
#区域私有方法
私有静态IWindsorContainer CreateContainer()
{
var container=新的WindsorContainer();
container.Install(fromsassembly.This());
返回容器;
}
#端区
}
[ServiceBehaviorAttribute(InstanceContextMode=InstanceContextMode.PerSession,ConcurrencyMode=ConcurrencyMode.Single)]
公共类CustomerService:ICCustomerService
{
专用只读IDataRepository_存储库;
专用只读ILogger\u记录器;
公共客户服务(IDataRepository存储库)
{
_存储库=存储库;
_logger=新的根记录器(Level.Error);
}
}
公共类服务安装程序:IWindsorInstaller
{
public void安装(IWindsorContainer、IConfigurationStore)
{
容器
.AddFacility(f=>
{
f、 CloseTimeout=TimeSpan.Zero;
})
.登记(
组成部分
.对于()
.由()实施
.短暂的
.AsWcfService(),
Component.For().ImplementedBy());
}
}

有人能看出我做错了什么吗?我想在服务启动时引导Windsors DI容器,并在创建WCF服务的实例时,让它在该点注入依赖项。

您可以有两个构造函数。其中,无参数调用将依赖项作为参数的重载

public WindowsService()
    this(new ServiceHost());

public WindowsService(ServiceHost serviceHost)
{ 
    this.ServiceHost = serviceHost;
}  

您可以使用所需的构造函数实例化服务实现,并将其作为参数传递给服务主机,例如

var service = CustomerService(container.Resolve<IDataRepository>());
ServiceHost = new ServiceHost(service);
var-service=CustomerService(container.Resolve());
ServiceHost=新的ServiceHost(服务);
或者,如果您正确配置了容器,则如下所示:

var service = container.Resolve<ICustomerService>();
ServiceHost = new ServiceHost(service);
var service=container.Resolve();
ServiceHost=新的ServiceHost(服务);
然而,在这种情况下,它将在单例模式下工作,我记得您需要将服务实现的InstanceContextMode更改为Single

1)您应该有两个构造器,正如另一张海报所建议的,一个构造器 默认值和以依赖项作为参数的值

2) 正如您在链接到的帖子中所看到的,您应该使用Castle的WCF设施 托管服务(请注意您发布的帖子中的
AsWcfService
语法 链接到)。你所要做的就是写城堡密码,注册 您的所有服务依赖项和Castle将负责 休息这简直就像魔术