代码之家  ›  专栏  ›  技术社区  ›  BartoszKP

为什么不能服务Unity的主机。如何正确解析服务实例?[副本]

  •  3
  • BartoszKP  · 技术社区  · 10 年前

    我有一个统一容器:

    var unityContainer = new UnityContainer();
    

    配置如下:

    unityContainer.RegisterType<IExampleDomainService, ExampleDomainService>();
    
    unityContainer.RegisterType<IExampleWebService, ExampleWebService>();
    

    ExampleWebService 类型及其构造函数如下所示:

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    public class ExampleWebService
    {
        public ExampleWebService(IExampleDomainService exampleDomainService)
        {
            this.exampleDomainService = exampleDomainService;
        }
    
    // ...
    

    ExampleDomainService 没有定义构造函数(当我为该类型显式定义无参数构造函数时,问题也是一样的)。

    接下来,如Unity.Wcf中所述 documentation :

    如果您在Windows服务中使用 ServiceHost ,更换 服务宿主 自定义的实例 Unity.Wcf.UnityServiceHost 。您会发现 UnityServiceHost 将Unity容器作为其第一个参数,但在其他方面与默认值相同 服务宿主 .

    我执行以下操作:

     var host = new UnityServiceHost(unityContainer, typeof(ExampleWebService), baseAddress);
    

    然而,这会引发 System.InvalidOperationException 并显示以下消息:

    提供的服务类型无法作为服务加载,因为它没有默认(无参数)构造函数。要解决此问题,请向类型添加默认构造函数,或将该类型的实例传递给主机。

    正在查看 UnityServiceHost implementation at GitHub 它通过给定 serviceType ( typeof(ExampleWebService) 在这种情况下)直接发送到WCF的本机 服务宿主 :

    public sealed class UnityServiceHost : ServiceHost
    {
        public UnityServiceHost(IUnityContainer container, Type serviceType, params Uri[] baseAddresses)
          : base(serviceType, baseAddresses)
                 ^^^^^^^^^^^
                 ???????????
    

    它显然崩溃了,因为 服务宿主 对Unity及其容器一无所知,当缺少无参数构造函数时无法处理。

    就是团结。对于非WAS/非IIS托管,我完全崩溃了,或者(我希望)我做了完全错误的事情?

    1 回复  |  直到 10 年前
        1
  •  3
  •   Community Mohan Dere    8 年前

    对不起,我不能告诉你为什么你有例外,但我希望能帮助你。

    1. ServiceHost 不需要对Unity有任何了解。DI通过 实施 IInstanceProvider 并为每个人注册 服务行为
    2. 它只对我有用,这是一个非常基本的应用程序 哪一个工作正常,也许你可以找到你的 一边

      public class Program
      {
          static void Main(string[] args)
          {
              var container = new UnityContainer();
              container.RegisterType<IDependency, Dependency>();
              container.RegisterType<IHelloWorldService, HelloWorldService>();
              Uri baseAddress = new Uri("http://localhost:8080/hello");
              using (ServiceHost host = new UnityServiceHost(container, typeof(HelloWorldService), baseAddress))
              {
                  ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
                  smb.HttpGetEnabled = true;
                  smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
                  host.Description.Behaviors.Add(smb);
      
                  host.Open();
      
                  Console.WriteLine("The service is ready at {0}", baseAddress);
                  Console.WriteLine("Press <Enter> to stop the service.");
                  Console.ReadLine();
      
                  host.Close();
              }
          }
      }
      
      [ServiceContract]
      public interface IHelloWorldService
      {
          [OperationContract]
          string SayHello(string name);
      }
      
      public interface IDependency
      {
      
      }
      
      public class Dependency : IDependency { }
      
      public class HelloWorldService : IHelloWorldService
      {
          private readonly IDependency _dependency;
      
          public HelloWorldService(IDependency dependency)
          {
              _dependency = dependency;
          }
      
          public string SayHello(string name)
          {
              return string.Format("Hello, {0}", name);
          }
      }
      
    3. WCF不调用 InstanceProvider 如果 InstanceContextMode.Single 习惯于这就是为什么团结。WCF无法使用它。可以找到详细答案 here .