首页 文章

WCF服务参考生成自己的 Contract 接口,不会重用我的

提问于
浏览
36

我的第一个问题是希望它是合适的:

Shared interface assembly - 我有一个'shared'程序集,它有一个接口,我们称之为 IDocRepository . 它标有 [ServiceContract] ,并且有几个 [OperationContract] 标记的方法 .

WCF implementation assemblies - 我有两个WCF服务项目,每个项目引用共享程序集,每个项目都将该接口实现为WCF服务 .

Consumer assembly - 最后,我有一个'client'项目,也引用了共享程序集,并引用了两个WCF服务 .

但是,使用者程序集中生成的服务引用来自自动生成的接口版本:

public partial class ExampleClient : System.ServiceModel.ClientBase<SomeNamespace.ExampleSvcRef.IDocRepository>, SomeNamespace.ExampleSvcRef.IDocRepository {

What I expected
我希望这两个引用都会自动继承我定义的接口,消费者/客户端程序集也引用它 . 有点像它为参数和返回类型提供的类的重用,但对于服务接口 .

Why
这样我就可以创建一个服务引用代理的实例并将其转换为我的接口类型 .

所以我每次都可以手工修改生成的代码,但应该有更好的方法......?

(编辑:我在两个服务引用中都选择了“在引用的程序集中重用类型”和“在所有引用的程序集中重用类型”选项)

4 回答

  • 3

    "Reuse types in referenced assemblies"仅允许您重复使用数据 Contract ,而不是服务 Contract . 如果您想共享服务 Contract ,则根本不需要使用"Add Service Reference" . 你可以直接使用ChannelFactory .

    // Supply the binding and address in code
    Binding binding = new BasicHttpBinding();
    EndpointAddress address = new EndpointAddress("http://tempuri.org/address");
    IServiceContract channel = ChannelFactory<IServiceContract>.CreateChannel(binding, address);
    
    // Or read them from the config file
    ChannelFactory<IServiceContract> channelFactory = new ChannelFactory<IServiceContract>();
    IServiceContract channel = channelFactory.CreateChannel();
    

    通道对象也将实现ICommunicationObject,因此如果需要调用Open()或Close()等方法,可以将其强制转换 .

  • 45

    创建服务引用时,可以勾选一个框以使其重用共享定义 . 确保客户端项目已引用共享程序集,再次添加服务引用,并仔细检查所有选项 .

    如果仍然无效,请检查您使用的绑定 . 我有一个模糊的回忆,基本的HTTP绑定不支持重用类型?

  • 4

    在为您生成代理类时,Visual Studio不支持重用现有接口 . Quartermeister指出,重用类型不会重用 Contract 接口 .

    我们用继承解决了它 . 与Jester Software建议的部分类思想非常类似 .

    这就是我们解决它的方式:

    在客户的项目中,只需像创建一样创建服务引用 . 然后添加一个用作客户端替换的类:

    internal class MyServiceProxy : MyServiceClient, MyLogicNamespace.IMyService
    {}
    

    此类继承自生成的MyServiceClient,但声明该客户端确实实现了原始接口 .

    (我建议你把它们放在一个名为“ServiceProxies”的文件夹中)

    如果MyServiceClient类包含与原始接口不匹配的任何方法,则可以在该代理中添加它们并在代码中进行转换 .

    在此之后,只需使用MyServiceProxy,您将使用MyServiceClient .

  • 2

    还有另一个不错的选择,如果你想继续使用代理生成器,因为它有限但有些有用的功能...使用部分类:

    namespace <same namespace as generated proxy>
    {
        public partial class MyClient : <namespace of "real" service contract>.IServiceContract
        {
        }
    }
    

    确保代理生成的代码与服务 Contract 定义代码的方式相同,即,如果它使用“列表”,则也使用配置服务引用中的该选项 . 换句话说,确保生成的服务接口与您的实际服务接口完全相同,并且上述代码应该可以工作,并且更新您使用的引用,而不是编写代码 .

相关问题