在添加服务引用生成的WCF数据服务和客户端之间共享POCO类型

时间:2012-09-21 06:48:57

标签: wcf service reference poco

我有一个WCF数据服务层,它暴露了POCO T4模板生成的POCO实体。这些POCO实体是在他们自己的项目(即Company.ProjectName.Entities)中创建的,因为我想尽可能地分享它们。

我在另一个项目(Company.ProjectName.Clients)中有一组接口,它们通过向Company.ProjectName.Entities.dll添加程序集引用来引用这些POCO类型。这些接口的一个实现是.NET客户端,我想使用WCF数据服务客户端库来使用该服务。

我使用添加服务引用添加服务引用。这生成了DataServiceContext客户端类和服务使用的POCO实体。但是,添加服务引用实用程序生成的这些POCO类型现在具有不同的命名空间(即Company.ProjectName.Clients.Implementation.WcfDsReference)。

这意味着接口中定义的POCO类型不能被实用程序生成的类型使用,而不必进行强制转换或映射。

即。假设我有:

 1. POCO Entity:     Company.ProjectName.Entities.Account
 2. Interface:       interface IRepository<Company.ProjectName.Entities.Account>{....}
 3. Implementation:  ServiceClientRepository : IRepository<Company.ProjectName.Entities.Account>
 4. WcfDsReference:  Company.ProjectName.Clients.Implementation.WcfDsReference
          &          Company.ProjectName.Clients.Implementation.WcfDsReference.Account


   Let's say I want to create a DataServiceQuery query on the Account, I won't be able to do this:

   var client = new WcfDsReference(baseUrl);
   var accounts = client.CreateQuery<Company.ProjectName.Entities.Account>(...)

      OR:         client.AddToAccounts(Company.ProjectName.Entities.Account)

   , because the CreateQuery<T>() expects T to be of type            &       Company.ProjectName.Clients.Implementation.WcfDsReference.Account

我目前要做的是将正确的实体传递给CreateQuery方法,并且必须将结果映射回接口理解的类型。 (可能使用映射器,但似乎不是一个好的解决方案。)

所以问题是,有没有办法让Add Service Reference实用程序生成使用Company.ProjectName.Entities命名空间中的POCO类型的方法?

我想到的一个解决方案是不使用该实用程序来生成DataServiceContext和其他类型,而是创建自己的类型。

另一种解决方案是更新IRepository<T>接口以使用该实用程序生成的POCO类型。但这听起来有点黑客。

有没有更好的解决方案,任何人都提出或有任何建议?

1 个答案:

答案 0 :(得分:1)

好的,在开始赏金后的几个小时,我发现为什么它在我的结束时没有按预期工作。

事实证明,共享过程非常简单。所有需要做的就是使用[DataServiceKey]属性标记模型类。 This article在“公开其他数据模型”部分

中很好地解释了这个过程

考虑到这一点,我试图做的是以下内容:

  1. 将模型放在单独的类库项目C上,与Web应用程序项目A和B共享
  2. 在项目A上创建数据服务
  3. 在项目B上添加服务参考
  4. 从服务引用中删除生成的模型代理,并将其更新为在项目C中使用我的模型类
  5. 将DataServiceKey属性添加到模型中,指定正确的键
  6. 当我尝试这个时它不起作用,给我以下错误:

      

    客户端和服务之间存在类型不匹配。类型   {MyType}不是实体类型,而是类型   响应有效负载表示实体类型。请确保类型   在客户端上定义的匹配服务的数据模型,或更新   客户端上的服务引用。

    此问题是由项目C(使用System.Data.OData程序集上的库存实现)与调用服务的客户端项目B(使用Microsoft.Data.OData程序集)之间的版本不匹配引起的。 packages)。通过匹配两端的版本,它第一次工作。

    在所有这些之后,仍然存在一个问题:服务引用过程仍未检测到要共享的模型,这意味着代理正在照常创建。这导致我选择退出自动服务集成机制,而不是强迫我继续使用我自己的简单类来作为Wcf数据服务的客户端。基本上,它是通常自动生成的类的严重修剪版本:

    using System;
    using System.Data.Services.Client;
    using System.Data.Services.Common;
    using Model;
    
    public class DataServiceClient : DataServiceContext
    {
        private readonly Lazy<DataServiceQuery<Unit>> m_units;
    
        public DataServiceClient(Uri _uri)
            : base(_uri, DataServiceProtocolVersion.V3)
        {
            m_units = new Lazy<DataServiceQuery<Unit>>(() => CreateQuery<Unit>("Units"));
        }
    
        public DataServiceQuery<Unit> Units
        {
            get { return m_units.Value; }
        }
    }
    

    这很简单,因为我只在readonly模式下使用该服务。我仍然希望使用服务引用功能,可能避免将来的维护问题,在这个简单的情况下由硬编码的EntitySet名称证明。目前,我正在使用此实现并完全删除了服务引用。

    我真的希望看到这与服务参考方法完全集成,如果有人可以共享解决方法,但这种自定义方法可以满足我们当前的需求。