WCF服务引用生成自己的契约接口,不会重用我的
我的第一个问题,所以希望它是适合的:
共享接口程序集 – 我有一个有共享接口的“共享”程序集,我们称之为IDocRepository
。 它标有[ServiceContract]
,有几个[OperationContract]
标记的方法。
WCF实现程序集 – 我有两个WCF服务项目,每个引用共享程序集,每个实现该接口作为WCF服务。
消费者组装 – 最后,我有一个“客户”项目,也引用了共享程序集,并引用了每个WCF服务。
但是,在使用者程序集中生成的服务引用来自接口的自动生成版本:
public partial class ExampleClient : System.ServiceModel.ClientBase<SomeNamespace.ExampleSvcRef.IDocRepository>, SomeNamespace.ExampleSvcRef.IDocRepository {
我所期望的
我希望这两个引用会自动inheritance我定义的接口,消费者/客户端程序集也是引用。 有点像重用它提供的参数和返回types的类,而是用于服务接口。
为什么
所以我可以创build一个服务引用代理的实例,并将其转换为我的接口types。
所以我可以每次手动修改生成的代码,但应该有更好的方法…?
(编辑:我确实有'在引用程序集中重用types'和'为所有服务引用select的所有引用程序集中的重用types'选项)
“在引用程序集中重用types”只允许重用数据契约,而不是服务契约。 如果您想分享服务合同,则根本不需要使用“添加服务参考”。 你可以直接使用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()这样的方法,你可以投它。
当您创build服务引用时,您可以勾选一个框以使其重用共享定义。 确保客户端项目已经引用共享程序集,再次添加服务引用,并仔细检查所有选项。
如果仍然不起作用,请检查您使用的绑定。 我有一个模糊的回忆,基本的HTTP绑定将不支持重用types?
还有一个不错的select,如果你想继续使用代理生成器,因为它是有限的,但有点有用的function…使用部分类:
namespace <same namespace as generated proxy> { public partial class MyClient : <namespace of "real" service contract>.IServiceContract { } }
确保代理以与服务合同定义相同的方式生成代码,也就是说,如果使用“列表”,则也可以在“configuration服务参考”中使用该选项。 换句话说,请确保您生成的服务接口与您真正的服务接口完全相同,并且上面的代码应该可以正常工作,并更新您使用的引用而不是编写代码。
Visual Studio不支持在为您生成代理类时重新使用现有的接口。 正如Quartermeister指出的那样,重用types不会重用合同界面。
我们用inheritance来解决它。 与Jester Software提出的部分类的想法非常相似。
这是我们如何解决它的:
在你的客户的项目中,只要创build一个服务引用就像你所做的那样。 然后添加一个类来替代客户端:
internal class MyServiceProxy : MyServiceClient, MyLogicNamespace.IMyService {}
这个类inheritance自生成的MyServiceClient,但声明客户端实现了原始接口。
(我build议你把它们放在名为“ServiceProxies”的文件夹中)
如果MyServiceClient类包含与原始接口不匹配的任何方法,则可以将其添加到该代理中,然后在代码中进行转换。
在此之后,只需使用MyServiceProxy即可使用MyServiceClient。