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

时间:2010-06-25 15:34:31

标签: c# wcf reference reusability

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

共享接口程序集 - 我有一个“共享”程序集,它有一个接口,我们称之为IDocRepository。它标有[ServiceContract],并且有几个[OperationContract]标记的方法。

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

消费者大会 - 最后,我有一个'客户'项目,也引用了共享程序集,并引用了两个WCF服务。

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

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

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

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

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

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

4 个答案:

答案 0 :(得分:45)

“在引用的程序集中重用类型”只允许您重用数据合同,而不是服务合同。如果要共享服务合同,则根本不需要使用“添加服务引用”。您可以直接使用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()等方法,可以进行投射。

答案 1 :(得分:4)

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

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

答案 2 :(得分:3)

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

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

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

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

internal class MyServiceProxy : MyServiceClient, MyLogicNamespace.IMyService
{}

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

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

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

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

答案 3 :(得分:2)

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

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

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