例如,我在IIS中托管了两个服务。
[ServiceContract]
public interface IDeviceService
{
[OperationContract]
DeviceCollection GetAllDevices(Customer customer);
}
[ServiceContract]
public interface IUserService
{
[OperationContract]
User Authenticate(string username, string password);
}
从UserService中的Authenticate操作返回的User对象和从DeviceService中的GetAllDevices操作返回的DeviceCollection都具有Customer的子对象定义。 Customer是一个业务对象与User和Device对象在同一个程序集中。
我的问题出在客户端 - 当我调用设备操作时
userProxy.GetAllDevices(user.Customer);
编译器抱怨以下消息:
参数1 - 无法从UserService.Customer转换为DeviceService.Customer
我可以很好地连接到这两个服务,这就是Customer的对象定义就是问题。我真的不想把操作放在他们看似在自己的服务中自然生活的相同服务中。我想我要问的是,其他程序员如何处理这样的问题?
干杯, 斯图尔特
答案 0 :(得分:3)
如果要跨多个服务共享数据协定,则必须将有问题的数据协定编译到自己的程序集中,然后将该程序集分发给客户端。
即使类型出现相同,它实际上是两种不同的类型,这就是您看到错误的原因。您唯一的其他选择(除了单独的共享程序集)是将两个服务合并为一个,以便他们可以共享数据协定。
答案 1 :(得分:2)
一种选择是在客户端上使用AutoMapper从一种类型无缝转换为另一种类型。因为它们具有相同的属性,所以映射是直截了当的。
答案 2 :(得分:0)
我以为我会尝试回答我自己的问题,详细说明我如何解决这个问题。它基于blog article by Dan Meineck上的一篇文章。
总结一下,我认为我为每个根业务实体提供多种服务的概念是错误的。
相反,我暴露了一个实现了几个DataContracts的服务,例如
public partial class DeviceService : IDeviceService, IUserService
{
}
因为设备服务是作为部分类创建的,所以我允许我将服务分开,我说它们是分开的,它们仍然是相同的服务但它允许我将它们分成单独的文件并为服务提供一些结构组织。
实现的最后一部分是在服务定义中声明两个端点,例如
<service behaviorConfiguration="GPSCloudHost.DeviceServiceBehavior" name="BusinessService.DeviceService">
<endpoint address="Device" binding="wsHttpBinding" contract="BusinessService.DataContracts.IDeviceService"></endpoint>
<endpoint address="User" binding="wsHttpBinding" contract="BusinessService.DataContracts.IUserService"></endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
我在WCF中没有经验,应该说这是否是“正确”的解决方案,但它正在满足我的要求。如果其他人有更好的解决方案,我很乐意听到它!
干杯
答案 3 :(得分:0)
这是一个语义问题。如果要将一个UserService.Customer和DeviceService.Customer定义为语义相等,那么您应该将该数据协定物理地重新分解为单独的程序集。或者,如果要将UserService.Customer和DeviceService.Customer定义为语义不同,则将它们保存为单独的类型,并编写实用程序函数以将其从一个转换为另一个。