【问题标题】:How to map models at different layers in Generic Repository Pattern如何在通用存储库模式中映射不同层的模型
【发布时间】:2018-01-13 09:58:54
【问题描述】:

这是关于通用存储库模式中的映射模型。

我的解决方案中有三层

  1. WebAPI 层 - APIModel
  2. DAL 层 - DALModel
  3. EF - EF 模型

所有层都在实现泛型。

我很纠结如何传递模型并将其映射到其他层的模型。

public class BaseController<Model> : ApiController
{
     // call to service
}  

public class BaseServices<Model>
{
    // call to dal repository
}

 public class BaseRepository<Model>
{
    // call to EF
}

问题/疑问

场景 1:

我可以将所有 3 个模型暴露给所有层。 IE。: public class BaseController&lt;APIModel, DALModel, EFModel&gt;。但这有必要吗?我不希望在所有图层上公开所有模型。我也不希望将 EFModel 用作在任何地方都可以使用的单一模型。

场景 2:

我只能将相关模型传递给每一层,即:

public class BaseController<APIModel>
public class BaseService<APIModel, DALModel>
public class BaseRepository<DALModel, EFModel>

如果这是应该做的,我应该把映射代码放在哪里?这意味着我如何将BaseService&lt;APIModel, DALModel&gt; 映射到BaseRepository&lt;DALModel, EFModel&gt;。我可以提供一些示例代码吗?

我在互联网上查看了一些示例代码,但找不到我需要的。

我只能想到这两种情况,如果有人能提供更好的解决方案,我将非常感谢。

【问题讨论】:

  • 但这有必要吗? 这都是意见问题。存储库层是必要的吗?
  • 但是如果模型暴露在所有层上,那么拥有不同的模型又有什么意义呢!你也是在暗示场景 2 是不可能的还是不推荐的!!
  • 这个站点上有很多编写良好的代码,它们遵循没有存储库的 ViewModel 模式(EF 是您知道的存储库)。您有未公开的实体模型和用于特定用例的视图模型和 AutoMapper 等工具,以减少摩擦。我们还没有遇到需要在此之上的另一层。当我们获得新的开发人员时,他们可以很快加入并理解代码。

标签: c# entity-framework generics asp.net-web-api repository-pattern


【解决方案1】:

场景 1:100% 不正确。 场景 2:不是好方法。

我认为下面的方法可以很好。

    public class BaseController<TService,DTO> : ApiController
    {
        private readonly TService _service;
        public BaseController(TService iService){
            _service = iService;
        }
        public List<DTO> GetAll(){
            return _service.GetAll();
        }
    }  

    public class BaseServices<IRepository,DTO>
    {
        private readonly IRepository _repo;
        public BaseServices(IRepository iRepository){
            _repo = iRepository;
        }
        public List<DTO> GetAll(){
            return _repo.GetAll().ToDTOList<DTO>();
        }
    }

     public class BaseRepository<Model>
    {
        public List<Model> GetAll(){
            return DB.Set<Model>().ToList();
        }
    }



    public class HomeRepository():BaseRepository<Home>{}
    public class HomeService():BaseServices<IHomeService,HomeDTO>{}
    public class HomeController():BaseController<IHomeService,HomeDTO>{}



        public static class Extensions
        {
           public static List<DTO> ToDTOList<DTO>(this IEnumerable<Model> entityList)   where DTO : class {
                return Mapper.Map<DTO>(model);
           }
       }

【讨论】:

  • 以下.. 假设我有 BaseService 类,我需要调用 BaseRepository 的方法,我如何将代码映射到 SModel 到 RModel。我无法在映射之前创建 BaseRepository 的对象。希望你能解决问题
  • 您可以编写扩展方法和映射模型到 DTO,反之亦然。
  • 使用AutoMapper 将一个对象映射到另一个对象。
  • 我知道伙计。我需要知道的是我应该把映射代码放在哪里?你能提供样品吗?我应该像 BaseRepositort 那样做吗??
【解决方案2】:

向上层公开你需要的模型。

代替:

public class BaseService<APIModel, DALModel>

只是做:

public class BaseService<APIModel>

在 BaseService 中,您使用 Automapper 从/到 DALModel 进行映射,因此 BaseService 类的用户不需要知道 DALModel。这是关注点的抽象和分离。您将能够在每一层中处理和修改您的数据传输模型,而不会影响上层。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-30
    • 1970-01-01
    • 2012-10-08
    相关资源
    最近更新 更多