为什么不能通过Unity.Wcf服务主机正确解析服务的实例?

时间:2016-01-07 16:04:13

标签: c# wcf unity-container .net-4.6

我有一个统一容器:

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&#39; documentation中所述:

  

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

我执行以下操作:

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

然而,这会使System.InvalidOperationException抛出以下消息:

  

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

查看UnityServiceHost implementation at GitHub,它将serviceType(在这种情况下为typeof(ExampleWebService))直接传递给WCF的原生ServiceHost

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

显然会崩溃,因为ServiceHost对Unity及其容器一无所知,并且在无参数构造函数丢失时无法应对。

对于非WAS /非IIS主机,Unity.Wcf是完全破坏还是(我希望)我做错了什么?

1 个答案:

答案 0 :(得分:3)

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

  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. 如果使用InstanceProvider,WCF不会致电InstanceContextMode.Single。这就是Unity.WCF无法使用它的原因。详细答案可以在here找到。