0

我们正在使用 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 在生成客户端代理代码时使用原始命名空间方案而不是它自己的?如果没有,这会影响我们“复制”库在客户端上的可用性吗?
  • 我可以在客户端上部署原始库吗?我想不会,但这会导致什么样的冲突?

谢谢你。

4

3 回答 3

1

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

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

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

于 2013-02-18T13:54:20.797 回答
1

根据我最近在一个非常大且旧的项目中实现 WCF 的经验,我会避免使用 Visual Studio 模板功能,例如瘟疫(对于大型项目),它只会让您头疼并在未来出现幻觉问题。

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

看看那篇文章。它回答了您当前的问题,并且可能会避免很多未来的头痛。

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

于 2013-02-18T14:12:03.920 回答
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();
于 2013-02-18T18:18:24.093 回答