【问题标题】:DI with Castle Windsor in Windows Service hosted WCF serviceDI 与 Castle Windsor 在 Windows 服务中托管 WCF 服务
【发布时间】:2013-10-18 13:05:04
【问题描述】:

我正在尝试让 Castle Windsor DI 与作为 Windows 服务托管的 WCF 服务一起工作。我已经采用了这里的方法

WCF Service Library hosted as a Windows Service using Castle.Windsor 3.0 issue

但是我遇到的问题是,如果我的服务实现类没有默认的无参数构造函数,ServiceHost 将不允许我在 OnStart() 中创建 this 的实例。如果我提供无参数构造函数,服务控制台会使用该构造函数启动服务,因此我不会注入任何依赖项。

代码如下

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>());
        }
    }

谁能看到我做错了什么?我想在服务启动时引导 Windsors DI 容器,并在创建 WCF 服务实例时为其注入依赖项。

【问题讨论】:

    标签: c# wcf castle-windsor


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        【解决方案3】:

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

        var service = CustomerService(container.Resolve<IDataRepository>());
        ServiceHost = new ServiceHost(service);
        

        或者甚至像这样,如果你已经正确配置了容器:

        var service = container.Resolve<ICustomerService>();
        ServiceHost = new ServiceHost(service);
        

        但是在这种情况下,它可以在单例模式下工作,我记得您需要将服务实现的 InstanceContextMode 更改为 Single

        【讨论】:

          猜你喜欢
          • 2013-08-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-01-13
          相关资源
          最近更新 更多