【问题标题】:WCF Problem with Proxy Class vs. Real Class代理类与真实类的 WCF 问题
【发布时间】:2009-10-02 13:45:50
【问题描述】:

我的控制台应用程序使用 WCF 服务。生成使用控制台应用程序命名空间的代理类。

DataAccess 层有一个 GetItems 方法,它需要一个属于不同命名空间的 ITEM 对象。有没有办法告诉 WCF 创建属于某个命名空间的项目,而不是使用客户端项目来创建命名空间!

更新

问题来了:

// The following namespace belongs in the class library project 
MYProject.Something.Foo foo = new Foo(); 
foo.Text = "hello world"; 

// Now the webservice has a method ProcessFoo but the proxy 
// class shows something like this: 
ProcessFoo(MyClientProject.Something.foo); 

我无法将我的 MYProject.Something.Foo 发送到 ProcessFoo 方法。

【问题讨论】:

    标签: wcf


    【解决方案1】:

    此服务是否只能由 .NET WCF 客户端调用?如果是这样,那么当您创建服务引用时,您可以告诉 WCF 共享现有类型,而不是创建返回类型的代理版本。

    当然,这只适用于 WCF 客户端。任何其他类型的客户端都需要使用代理类,这就是您所处的情况。

    请参阅Basics: How Web Services Work 了解说明。我最初写的是关于 ASMX Web 服务的,但它适用于一般的 Web 服务。

    【讨论】:

    • 我删除了服务并再次添加它并告诉 WCF 使用类库程序集中的类型,但它只是生成了具有自己命名空间的代理类!
    • 你的客户项目是否引用了类库?库是否显示在程序集列表框中?
    • 是的,库显示在程序集列表中。我选择 dll 并创建服务。但是当我检查 reference.cs 文件并检查 AddCustomer 方法的参数时,它表明该方法仍在使用客户端(控制台应用程序)命名空间。
    【解决方案2】:

    更新

    原来我完全误解了你原来的问题。您可以手动将 MYProject.Something.foo 对象的属性复制到 MyClientProject.Something.foo ,或者,如果这是您经常使用的操作,您可以实现某种转换例程,以便您可以这样做:

    MYProject.Something.Foo foo = new Foo(); 
    foo.Text = "hello world"; 
    
    ProcessFoo((MyClientProject.Something.foo)foo);
    

    原创

    任何时候你创建一个对象,你总是可以使用它的全名来指定命名空间:

    SqlConnection conn = new SqlConnect();
    

    等价于

    System.Data.SqlClient.SqlConnection conn = 
        new System.Data.SqlClient.SqlConnection();
    

    【讨论】:

    • 这里是问题所在: // 下面的命名空间属于类库项目 MYProject.Something.Foo foo = new Foo(); foo.Text = "你好世界";现在 web 服务有一个方法 ProcessFoo 但代理类显示如下: ProcessFoo(MyClientProject.Something.foo);我无法将我的 MYProject.Something.Foo 发送到 ProcessFoo 方法。
    • 转换对我来说将是一个非常痛苦的过程!
    【解决方案3】:

    我将建议一个替代方案来做你想做的事情:

    我建议不要重新编写代码以便通过 Web 服务将 MyProject.Something.Foo 类传递给您。原因如下:

    通过在服务合同中使用您的 MyProject.Something.Foo 类,您将该类与您的 Web 服务紧密耦合,因此也耦合了您的 Web 服务的客户端,这些客户端需要生成自己的客户端代理(或相等的)。这种耦合使您将来很难更改隐藏在服务合同后面的逻辑的实现,因为如果您进行的更改涉及更改类的公共接口,则必须重新生成代理并更改由您的 Web 服务发布的合同。您的所有客户也将如此。

    相反,我建议您使用 svcutil 生成代理;保持您的 MyProject.Something.Foo 类(这是您的业务逻辑层)分开;并编写一些代码在它们之间进行映射。然后,您更有可能吸收对业务逻辑类的更改,而无需中断和重新生成服务合同。

    我想要了解的是 SOA 设计原则(被称为“服务共享架构和合同,而不是类”)(不是很有说服力,已经读过这篇文章)——给这个谷歌,看看你的想法。

    希望对您有所帮助!

    【讨论】:

    • 在客户端类和业务类之间创建映射的问题是我必须为所有客户端执行此操作。如果所有客户都可以使用商务舱,那就太好了。这样就不需要映射了。 PS:类之间的映射很复杂,因为它涉及到属于不同类的枚举。
    • 为了清楚起见,我建议在您的服务器端 Web 服务代理和您的业务逻辑类之间进行映射 - 不涉及客户端。这额外的工作;但它增加了抽象层,可以很好地保护您免于以后昂贵地破坏您的 Web 服务合同。
    【解决方案4】:

    您可以使用 import 语句为类命名,避免命名冲突:

    import MyProject; // MyProject.Something
    import ServiceSomething = MyClientProject.Something;
    

    现在您可以在同一个类/代码文件中引用这两种类型,将服务代理类称为ServiceSomething

    编辑:我实际上建议您不要与网络服务代理共享您的实体。它使版本控制变得更加困难。只需创建一个来回映射实例的静态 SomethingMapping 类,然后永远不要在使用代理的类之外使用 Web 服务代理类。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-20
      • 1970-01-01
      • 2022-01-20
      • 2022-09-29
      • 1970-01-01
      相关资源
      最近更新 更多