40

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

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

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

消费者程序集——最后,我有一个“客户端”项目,它也引用了共享程序集,并引用了两个 WCF 服务中的每一个。

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

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

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

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

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

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

4

4 回答 4

46

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

于 2010-06-25T22:54:11.917 回答
4

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

我们已经通过继承解决了这个问题。与上面 Jester Software 建议的部分类思想非常相似。

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

在您的客户的项目中,只需像您所做的那样创建一个服务引用。然后添加一个类作为客户端的替代品:

internal class MyServiceProxy : MyServiceClient, MyLogicNamespace.IMyService
{}

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

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

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

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

于 2013-06-26T11:29:35.253 回答
3

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

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

于 2010-06-25T15:37:01.003 回答
2

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

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

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

于 2011-09-02T16:54:18.833 回答