我正在用MVC框架使用Asp.NET核心开发一个应用程序。我想询问您对我是否将存储库很好地注入到我的业务层的意见。
首先,让我们看看我的IRepository接口:
public interface IRepository<T>
{
IEnumerable<T> GetAll();
T Get(long id);
void Insert(T entity);
void Update(T entity);
void Delete(T entity);
}让我们看看我的一个服务类:
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,它负责映射和排序来自数据库的数据:
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?也许你对我的代码还有什么其他的评论吗?
发布于 2017-07-31 18:06:08
将存储库或其他任何东西注入业务层是一个总体上的坏主意。您的业务层应该不受框架机制的影响。你会用不必要的复杂性污染你最重要的部分。
您可以做的是将DI放在某些对象中,这些对象将初始化业务层周围的依赖项。因此,您可以使用"RepositoryProvider“作为依赖于DI的伪制品,它将初始化独立于DI的、由业务层使用的"RepositoryRegistry”。
保持您的业务层清洁。
发布于 2017-07-31 19:27:25
您的存储库实现很好。然而,通常在服务中,我只处理业务/域对象。我不会在那里返回一个视图模型。我只返回一个域对象。让表示层(如果有)处理从域对象到视图模型的映射。如果是MVC/Web,则在控制器中执行。viewmodel类只存在于视图项目中。
https://codereview.stackexchange.com/questions/171675
复制相似问题