如何在wcf中使用注入

时间:2011-05-27 22:25:18

标签: wcf

我有两个类在服务上实现合同,这些类在客户端的工厂消耗,如下所示。

[ServiceContract]
public interface MyInterface {
    void DoSomething()
}


public class A : MyInterface {
    public void DoSomething(){
       "Hi I'm A"
    }
}

public class B : MyInterface {
     public void DoSomething(){
         "Hi I'm B"
     }
}

public class MyFactory <TMyInterface> {
     void DoSomething(){
         TMyInterface.DoSomething()
     }
}

客户必须保持不变。我的问题是如何通过在WCF中使用.config文件传递type参数,在服务器端选择使用哪个MyInterface实现

我读了其他帖子,但我还不明白:(

1 个答案:

答案 0 :(得分:1)

可以这样做,并且有几种方法可以做到。

一种可能性是创建一个“路由”服务,该服务将包含客户端始终与之对话的“公共”地址。然后,此路由服务可以根据某些配置将呼叫重定向到适当的“真实”服务。

另一种方法是实际上有一个启动两个服务的进程,但是它们的地址是在config中定义的。如果您使用相同的绑定和相同的合同(在这种情况下),那么当您想要更改将从客户端接收呼叫的服务时,您可以“翻转”服务地址。例如,此配置将请求定向到服务A的“http:// machine-name:8000 / Service”端点。请注意,由于您为两个服务定义服务主机,因此实际上需要具有服务B - 在这种情况下我使用命名管道,不能通过不同的机器访问。

  <system.serviceModel>
    <services>
      <service name="A">
        <host>
          <baseAddresses>
            <add baseAddress="http://machine-name:8000/Service"/>
          </baseAddresses>
        </host>
        <endpoint address="" binding="basicHttpBinding" contract="MyInterface" />
      </service>
      <service name="B">
        <host>
          <baseAddresses>
            <add baseAddress="net.pipe://localhost/ServiceBackup"/>
          </baseAddresses>
        </host>
        <endpoint address="" binding="netNamedPipeBinding" contract="MyInterface" />
      </service>
    </services>
  </system.serviceModel>

当您想要更改B的地址时,您需要交换地址。

  <system.serviceModel>
    <services>
      <service name="A">
        <host>
          <baseAddresses>
            <add baseAddress="net.pipe://localhost/ServiceBackup"/>
          </baseAddresses>
        </host>
        <endpoint address="" binding="netNamedPipeBinding" contract="MyInterface" />
      </service>
      <service name="B">
        <host>
          <baseAddresses>
            <add baseAddress="http://machine-name:8000/Service"/>
          </baseAddresses>
        </host>
        <endpoint address="" binding="basicHttpBinding" contract="MyInterface" />
      </service>
    </services>
  </system.serviceModel>

主机程序如下所示:

public static void HostServices()
{
    ServiceHost hostA = new ServiceHost(typeof(A));
    ServiceHost hostB = new ServiceHost(typeof(B));
    hostA.Open();
    hostB.Open();
    Console.WriteLine("Press ENTER to close");
    Console.ReadLine();
    hostA.Close();
    hostB.Close();
}

现在,如果您的服务托管在IIS(webhost)中,那么它就更难了。由于“正常”激活需要.svc文件作为端点地址的一部分,并且每个.svc文件与单个类相关联,因此A的地址类似于http://machine-name/services/a.svc,而B的地址则为就像http://machine-name/services/b.svc。因此,在这种情况下,您需要做的是创建自定义ServiceHostFactory,并使用ASP.NET Routes集成为您的服务创建.svc-less URL。然后,您将使用与前一个示例类似的内容来确定将激活哪个服务。