WCF代理代码中的“复制”类

时间:2013-02-18 13:41:11

标签: .net wcf architecture

我们正在使用WCF和Visual Studio 2008来构建大型分布式应用程序。我们对WCF没有太多经验,因此我们花了一些时间来对客户端和服务器之间的WCF通信进行原型设计。我们观察到,我们的服务器子系统中的WCF服务作为参数或返回类型引用的任何类都由Visual Studio通过生成的代码“复制”到客户端代理中。我发现令人惊讶的是,在执行此操作时,Visual Studio会更改类的名称空间。例如,假设我有以下代码:

namespace MyLibrary
{
    class MyClass
    {
        //...
    }
}

想象一下,我将其编译成MyLibrary.dll,我的WCF服务有一个引用。我的一些WCF服务使用MyLibrary.MyClass作为返回类型。当我查看生成的客户端代理代码时,我发现MyClass是自动可用的(这很酷),但它不再位于MyLibrary命名空间中,而是由Visual Studio生成的一个。

我们计划有一个复杂的域对象模型,其中有数百个类分布在多个程序集中,我担心这将在Visual Studio的代码生成过程中“移植”。此外,我担心我们设计的所有名称空间层次结构可能都会丢失。我们最初的愿景是为这个域对象模型创建类库,并在服务器和客户端上对其进行处理。但由于WCF魔术似乎为必要的类生成代码,我想如果我们在客户端部署我们自己的库,就会发生冲突。

我有两个具体问题:

  • 有没有办法让Visual Studio在生成客户端代理代码时使用原始命名空间方案而不是自己的方案?如果没有,这会影响我们在客户端上“复制”的库的可用性吗?
  • 我可以在客户端上部署原始库吗?我想不到,但是会造成什么样的冲突呢?

谢谢。

3 个答案:

答案 0 :(得分:1)

添加服务引用时,可以单击“高级”按钮,在那里可以选中“重用引用程序集中的类型”复选框。您还需要确保包含客户端项目中引用的原始类型的程序集。

您当然可以在客户端部署原始库。

WCF这样做的原因 - 概念是服务可以由没有原始二进制文件的客户端使用,甚至不支持.net(例如Java) - 因此服务边界发布所有内容客户需要为了调用它,并处理它的响应。

答案 1 :(得分:1)

根据我最近在一个非常大的项目中实施WCF的经验,我会避免使用像瘟疫这样的Visual Studio模板功能(对于大型项目),它会让你头疼和幻想问题。 / p>

http://www.codeproject.com/Articles/114139/WCF-The-Right-Way-A-Quick-Reference-Guide

查看那篇文章。它回答了您当前的问题,可能会避免很多未来的麻烦。

除了上述内容之外,如果您的传输层具有良好的实现和隔离,则可以绝对重用组件,这是不使用VS模板的一个重要原因。

答案 2 :(得分:0)

您最初的愿景是完全可能的。一种避免visual studio生成客户端的方法,是创建一个与服务器共享库服务接口的通用客户端,以及绑定的实现(后者不是必需的,可以使用相同的服务器/ app.config中的客户端绑定配置,但如果最终设置类似,则很方便。)

一些客户端c#示例代码来实现这个想法:

        // simplified extract from a generic service client lib, 
        // needs error mgmt channel disposal etc but the concept is there

        // BindingFactory is our common implementation with server, 
        // bindingType is an enumeration, this could be built from 
        // configuration though or however you want
        var binding = BindingFactory.CreateBinding(bindingType);

        var endpointAddress = new EndpointAddress(serviceAddress,
                     EndpointIdentity.CreateSpnIdentity(string.Empty))
        var channelFactory = new ChannelFactory<IMyLibrary>(
            binding, endpointAddress);

        var channel = channelFactory.CreateChannel();

        // IMyLibrary is the interface implemented 
        // by the service found on serviceAdress
        var result = ((IMyLibrary)channel).MyServiceFunction();