首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将存储库注入业务层

将存储库注入业务层
EN

Code Review用户
提问于 2017-07-31 17:26:04
回答 2查看 1.3K关注 0票数 2

我正在用MVC框架使用Asp.NET核心开发一个应用程序。我想询问您对我是否将存储库很好地注入到我的业务层的意见。

首先,让我们看看我的IRepository接口:

代码语言:javascript
复制
public interface IRepository<T>
{
    IEnumerable<T> GetAll();
    T Get(long id);
    void Insert(T entity);
    void Update(T entity);
    void Delete(T entity);
}

让我们看看我的一个服务类:

代码语言:javascript
复制
public interface IContainersGridService
{
    IList<ContainerGridViewModel> GetGridViewModels(string searchText);
}

public class ContainersGridService : IContainersGridService
{
    private readonly IRepository<Container> _containersRepository; //TODO: when write test, test when throws same db exception
    private readonly IContainerGridViewModelsGetter _containerGridViewModelsGetter;

    public ContainersGridService(IRepository<Container> containersRepository, IContainerGridViewModelsGetter containerGridViewModelsGetter)
    {
        _containersRepository = containersRepository;
        _containerGridViewModelsGetter = containerGridViewModelsGetter;
    }

    public IList<ContainerGridViewModel> GetGridViewModels(string searchText)
    {
        var containers = _containersRepository.GetAll();
        return _containerGridViewModelsGetter.Get(containers, searchText);
    }
}

如您所见,我有一个带有基本CRUD方法签名的IRepository接口。我还有一个ContainersGridService,它负责从数据库中获取一些容器(域:转储容器)。

此外,我还注入了一个ContainersGridService,它负责映射和排序来自数据库的数据:

代码语言:javascript
复制
public interface IContainerGridViewModelsGetter
{
    IList<ContainerGridViewModel> Get(IEnumerable<Container> containers, string searchText);
}

public class ContainerGridViewModelsGetter : IContainerGridViewModelsGetter
{
    private readonly IContainerMappingService<ContainerGridViewModel> _containerMappingService;
    private readonly IContainersGridGlobalSearcher _containersGridGlobalSearcher;

    public ContainerGridViewModelsGetter(IContainerMappingService<ContainerGridViewModel> containerContainerMappingService, IContainersGridGlobalSearcher containersGridGlobalSearcher)
    {
        _containerMappingService = containerContainerMappingService;
        _containersGridGlobalSearcher = containersGridGlobalSearcher;
    }

    public IList<ContainerGridViewModel> Get(IEnumerable<Container> containers, string searchText)
    {
        var containerGridViewModels = GetContainerGridViewModels(GetSortedContainers(containers));

        return _containersGridGlobalSearcher.Search(containerGridViewModels,searchText);
    }

    private List<ContainerGridViewModel> GetContainerGridViewModels(IEnumerable<Container> sortedContainers)
    {
        return sortedContainers
            .Select(c => _containerMappingService.Map(c))
            .ToList();
    }

    private IEnumerable<Container> GetSortedContainers(IEnumerable<Container> containers)
    {
        return containers.OrderBy(c => c.DesiredTakeUpDate);
    }
}

正如您所看到的,我在这里注入了另外两个逻辑类(一个映射和一个搜索)。此时,我想知道这是否是用存储库实现业务层的最佳方法。

首先,我想将我的存储库注入到ContainerGridViewModelsGetter中,但后来我意识到,如果我将存储库从这个逻辑类中分离出来,并且只将一个IList传递给我的ContainerGridViewModelsGetter.Get(...)方法,(也许)更好。使用这种方式,我将数据从该类中分离出来,因此相应的测试也更加清晰和清晰。

我的问题如下:这是将我的存储库注入到我的服务层的好方法吗?或者我会把IRepository注入我的ContainerGridViewModelsGetter?也许你对我的代码还有什么其他的评论吗?

EN

回答 2

Code Review用户

发布于 2017-07-31 18:06:08

将存储库或其他任何东西注入业务层是一个总体上的坏主意。您的业务层应该不受框架机制的影响。你会用不必要的复杂性污染你最重要的部分。

您可以做的是将DI放在某些对象中,这些对象将初始化业务层周围的依赖项。因此,您可以使用"RepositoryProvider“作为依赖于DI的伪制品,它将初始化独立于DI的、由业务层使用的"RepositoryRegistry”。

保持您的业务层清洁。

票数 1
EN

Code Review用户

发布于 2017-07-31 19:27:25

您的存储库实现很好。然而,通常在服务中,我只处理业务/域对象。我不会在那里返回一个视图模型。我只返回一个域对象。让表示层(如果有)处理从域对象到视图模型的映射。如果是MVC/Web,则在控制器中执行。viewmodel类只存在于视图项目中。

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/171675

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档