我有两个项目,一个是一组WCF服务(让我们调用P1),另一个是标准Web应用程序(P2)。
首先,我们在P2中使用P1服务作为SOAP服务,一切都很顺利。后来我们注意到,在我们的所有项目部署中,我们都在托管P1& P2在同一台服务器上。所以我们想为什么要保持这样 - 意思是:为什么我们应该在每个方法在同一服务器上运行时每次都对请求/响应进行序列化/反序列化。因此我们决定在P2中使用P1作为标准项目库参考。
我们必须进行大量修改,因为代理类名称会更改,并且必须在每次调用后删除客户端“close”方法。现在,我们有一个新的部署,需要P1在与P2不同的服务器上,我们可以更改,我们必须再次使用P1作为WCF服务 - 意味着在整个P2上进行大量更改并以序列化结束所有其他部署的开销!
问题是,有没有办法对P1进行这样的动态引用,因此无论部署在1台还是2台服务器上都不需要编码?
答案 0 :(得分:2)
可以使WCF服务运行本地(项目引用)或基于web.config上的某个键作为服务运行。我做了以下示例,但我没有测试它,但我在
之前完成了类似的事情在web配置中添加密钥,说serviceMode =“local / service”
然后说你有wcf服务接口
[ServiceContract]
public class ICalculator
{
[OperationContract]
int Add(int x, int y);
}
实施
public class Calculator
{
public int Add(int x, y)
{
return x+y;
}
}
///现在在您的网络应用程序中
你会有
public LocalProxy:ICalculator //this will use direct instance of the Calculator Service
{
private ICalculator _calculator
public LocalProxy(ICalculator calculator)
{
_calculator =calculator;
}
public int Add(int x, int y)
{
return _calculator.Add(x,y);
}
}
public class RemoteProxy:ICalculator ///This will be real wcf proxy
{
public int Add (int x,int y)
{
var endpointAddress = new EndpointAddress(EndpointUrl);
ChannelFactory<ICalculator> factory = null;
ICalculator calculator ;
try
{
// Just picking a simple binding here to focus on other aspects
Binding binding = new BasicHttpBinding();
factory = new ChannelFactory<ICalculator>(binding);
calculator= factory.CreateChannel(endpointAddress);
if (calculator== null)
{
throw new CommunicationException(
String.Format("Unable to connect to service at {0}", endpointUrl));
}
int sum= calculator.Add(x,y);
((IClientChannel)calculator).Close();
calculator = null;
factory.Close();
factory = null;
return sum;
}
finally
{
if (calculator!= null) ((IClientChannel)calculator).Close();
if (factory != null) factory.Abort();
}
}
}
现在你如何使用它
ICalculator _calculatorProxy;
//get the web config key here, you may use strategy pattern to select between the two proxies
if(key=="local)
{
_calculator= new LocalProxy(new Calculator)
}
else
{
_calculator= new RemoteProxy();
}
//then
_calculator.Add(3,5);
注意:在单独的程序集中定义接口和数据协定,以便可以与需要wcf作为服务运行的Web应用程序共享它。
答案 1 :(得分:1)
P2中使用P1服务的所有组件都应该只使用服务接口(即IMyService
,ISomeOtherService
)。他们不应该关心它是本地实例还是代理,也不应该关闭连接。
最简单的(imho)意识到这一点是通过像温莎城堡这样的IoC使用依赖注入(它是我唯一熟悉的,但还有其他几个)。容器将负责提供服务接口的实例。您可以提供不同的实现,并在运行时使用适当的容器(WCF服务或本地实例)配置容器。一旦不再需要服务组件,容器也将负责处理它们(即在WCF代理上调用Close()
而不为其他代理执行任何操作)。
这是一个很大的话题,所以我建议你在互联网上搜索一些关键词 - 那里有很多资料。