2011-05-27 25 views
0

我有两个类实现服务中的合同,这些合同在客户端的工厂中使用,如下所示。如何在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() 
    } 
} 

客户端必须保持不变。我的问题是我怎么能选择在服务器端使用哪种实现MyInterface的,而应使用合格的类型参数config文件中WCF

我读其他职位,但我还不明白:(

+0

图片中的WCF在哪里? MyInterface是服务合同吗?您是否试图在客户端或服务器上调用MyFactory .DoSomething? – carlosfigueira 2011-05-27 22:34:02

+0

MyFactory必须是来自我的客户端的服务合约我只想致电工厂,服务负责根据他的配置来解决和使用实施 – TedTel 2011-05-27 22:50:45

+0

因此,您不想更改客户端代码或配置,但根据* server * config更改在服务器端调用哪个类? – carlosfigueira 2011-05-28 15:05:46

回答

1

有可能做到这一点,有几种方法可以做到这一点

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

另一种方法是将通常有一个启动这两个服务的过程,但他们的地址是在config中定义的。如果您使用相同的绑定和相同的合同(情况如此),那么当您想要更改将接收来自客户端的呼叫的服务时,您可以“翻转”服务地址。例如,该配置将请求发送到端点“http:// machine-name:8000/Service”到服务A.请注意,由于您为两个服务定义了服务主机,实际上您需要有一个基地址服务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(主机服务商)托管,那么它是一个有点困难。由于“正常”激活需要将.svc文件作为端点地址的一部分,并且每个.svc文件都与一个类关联,所以A的地址应该类似于http://machine-name/services/a.svc,而B的地址应该类似于http://machine-name/services/b.svc 。所以在这种情况下你需要做的是创建一个自定义的ServiceHostFactory,并使用ASP.NET Routes集成为你的服务创建一个.svc-less的URL。然后你会使用类似于前面例子的东西来决定哪个服务将被激活。

+0

我很欣赏你的答案,我会尝试实现你的想法并在稍后发布我的结果,但是对我来说很快就会有一个很好的解决方案谢谢! :) – TedTel 2011-05-29 17:48:36