I am developing an application using Asp.NET core with MVC framework. I would like to ask your opinion about whether I inject my repository in a good way into my business layer.
First of all, lets see my IRepository interface:
public interface IRepository<T>
{
IEnumerable<T> GetAll();
T Get(long id);
void Insert(T entity);
void Update(T entity);
void Delete(T entity);
}
Lets see one of my service class:
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);
}
}
As you can see I have an IRepository
interface with the basic CRUD method signatures. I also have a ContainersGridService
which is responsible to get some containers (domain: dump containers) from the database.
Furthermore, I have an ContainersGridService
injected which is responsible for mapping and sorting the data coming from the database:
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);
}
}
As you can see, I have injected two additional (one mapping and one searching) logic class here. At this point I am wondering if it is the best way to implement my business layer like this, with the repository.
First I wanted to inject my repository into the ContainerGridViewModelsGetter
but later I realized that it is (maybe) better if I separate the my repository from this logic class and I only pass an IList
to my ContainerGridViewModelsGetter.Get(...)
method. Using this way, I separated the data from this class, so the corresponding tests are also cleaner and clearer.
My questions are the following: Is it a good way to inject my repository to my service layer? Or maybe I would have injected the IRepository
into my ContainerGridViewModelsGetter
? Maybe do you have any other remarks regarding my code generally?