在WCF服务中如何解决引用不明确的问题是什么?

3

项目结构

我有一个名为SLProj的Silverlight项目,引用了一个名为ServiceClients的Silverlight类库项目。ServiceClients有两个wcf服务引用,Svc1.svc和Svc2.svc。Svc1.svc和Svc2.svc都在两个不同的WCF项目中,这两个项目使用相同的DataContract,这些DataContract再次在另一个类库项目MyDataContracts.dll中。

问题描述

现在,在我的ServiceClients项目中,当我需要使用同时存在于两个服务引用中的DataContract类时,我会遇到模糊引用的问题。如果这是一个WinForms或WebForms项目,我可以引用MyDataContracts.dll并重用公共类型。但由于这个MyDataContracts.dll是使用非Silverlight类库构建的,无法被Silverlight项目引用。

解决方案...

我不确定以下是否是处理此问题的最佳方法。有没有人可以告诉我是否有更清晰的方法来解决这个问题,或者这是目前我们拥有的最好方法?

  • create a single service reference.
  • click the 'show all files' button in the solution explorer
  • drill into the service reference and find Reference.svcmap and open it
  • find the MetadataSources section
  • add a second line to include the address to your second service. for example:

    MetadataSource Address="http://address1.svc" Protocol="http" SourceId="1" 
    MetadataSource Address="http://address2.svc" Protocol="http" SourceId="2" 
    
  • save, close, and update service reference.

2个回答

2

使用AutoMapper

使用AutoMapper来映射DataContract

你需要花费一些时间来了解AutoMapper并重新设计你的应用程序。而且,AutoMapper增加了开销,因为所有的数据对象都会被映射。但是,首先你将拥有一个干净的解决方案而没有任何的黑客行为,其次你将获得一个专门为你的客户端编写的解耦和简单的数据对象层。完成之后,你可以忘记映射,但是你仍然保持着对未来变化的灵活性。

如果你还没有使用过Automapper,那么在开始之前玩一下它是很重要的。Automapper是特别的,需要一些时间来熟悉它。

以下是大致步骤:

1. 创建一个子目录和子命名空间Data,并复制DataContracts。移除你的客户端不需要的属性和属性标记,因为这些映射类只存在于你的客户端。你还可以更改一些类型或者展开一些复杂的属性。

2. 创建一个AutoMapperInit.cs,像AutoMapper中描述的那样(阅读入门指南)。使用如下冲突引用:

using ref1 = YourProjectServiceReference1;
using ref2 = YourProjectServiceReference2;

3. 将服务客户端封装如下:

Example GetExample() {
    return AutoMapper.Map<ref1.Example, Example>(ref1.YourService.GetExample());
}

包装器还需要与步骤2相同的using指令。

4. 在此包装器中添加一个静态初始化程序,如下所示(假设您的包装器类名为Wrapper):

static Wrapper() {
    AutoMapperInit.CreateMaps();
}

5. 在客户端中省略服务引用,使用你在步骤1中创建的命名空间using YourClient.Data;

现在你的客户端已从服务中解耦,不再存在冲突。

免责声明:本人与AutoMapper无关。我只是在一个类似的问题项目中使用了它,并对它感到满意,想要分享我的经验。


哇,感谢您提供详细的步骤。不幸的是,我已经标记了一个正确的答案。而且我已经很久没再使用Silverlight了 :) 但我相信这个答案会帮助其他人。再次感谢您的详细努力。干杯。 - user20358
不客气。顺便说一下,我不使用Silverlight,但是你的问题适用于所有WCF客户端。 - nalply

1

你的解决方法其实还不错。我们在几个类似有三个服务引用的项目中都使用了它。这实际上是一个IDE的解决方法,因为出于某种原因,它只允许一次选择一个服务来创建服务引用。

另外一个你可以尝试的方法是将你的共享契约多目标到.NET和Silverlight,使用相同的代码库。如何做到这一点的详细信息在http://10rem.net/blog/2009/07/13/sharing-entities-between-wcf-and-silverlight中有描述。可能需要更多的工作,但感觉不那么hacky。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接