ServiceLayer

Mar 21, 2014 at 11:22 PM
Edited Mar 23, 2014 at 12:19 AM
Hi, thank you Le Long for your great framework.
I'm currently trying to implement the patterns into my project but I’m struggling with some kind of service layer things.
  1. You just use UnitOfWork in your Controller classes. Shouldn't that be nested in the business logic in the service layer?
  2. If i have really complex queries with a lot (A LOT) of objects and a lot of data, how should i initialize my service? Should i add all affected repositories to the constructor? I know no generic way to achieve this in your framework. Or did I miss something? Right now we are using native sql queries for this. How could i call a service with a native query? QueryObject?
  3. For the complex queries it could be nice to use some kind of DTOs. But I’m not sure how to extend the service layer to do that :( I guess i have to extend Service and Repository?
Sorry if I understand something completely wrong, but I’m kind of new to asp.net mvc.

Thank you!
Mar 23, 2014 at 12:19 AM
I've thought about the scenario to use UnitOfWork in my service layer. It was quite simple to change your code a little bit and get my desired result. (I hope so)

I've changed the constructor of the service and replaced the following code:
private readonly IRepositoryAsync<TEntity> _repository;
protected Service(IRepositoryAsync<TEntity> repository)
{
             _repository = repository;
}}
with:
private readonly IRepositoryAsync<TEntity> _repository;
protected readonly IUnitOfWorkAsync _unitOfWork; // added UnitOfWork interface
protected Service(IUnitOfWorkAsync unitOfWork) // changed constructor 
{
            _unitOfWork = unitOfWork;
            _repository = unitOfWork.RepositoryAsync<TEntity>(); // calling existing function in unitOfWork to get/create the repository
}
The advantage for me is that I can easily access the repositories and the unitOfWork in my service layer.

In additon i could remove all Unity configurations like:
.RegisterType<IRepositoryAsync<Customer>, Repository<Customer>>()
.RegisterType<IRepositoryAsync<Product>, Repository<Product>>()

Do I have any disadvantages to do it that way?
Coordinator
Mar 23, 2014 at 12:32 AM
Edited Apr 7, 2014 at 2:19 AM
  1. This is totally up to the team and what works best for them, preferably we prefer to leave them outside the services so you have find grain control of when and where you commit your unit of work.
  2. Some teams inject all repositories needed into their Services and other access them the IRepository or IUnitOfWork, enterprise teams usually go with option 1, which is injecting all repositories into their Services so that it's easier for them to mock and unit test later as well as better visibility and clarity what the Service concerns are by looking at the Constructor.
  3. Please review https://genericunitofworkandrepositories.codeplex.com/wikipage?title=Adding%20Custom%20Queries%20to%20Repository, there is a sample where we return CustomerOrder which could be a DTO (wrapper) in your case. You don't need to implement it in the same exact way, however this intended to get your started.
Accessing from Repository Sample,
var customerRepository = repository.GetRepository<Customer>();
var orderRepository = repository.GetRepository<Order>();
Accessing from IUnitOfWork Sample
var customerRepository = _unitOfWorkAsync.Repository<Customer>();
var customerRepository = _unitOfWorkAsync.Repository<Order>();
Marked as answer by lelong37 on 4/6/2014 at 6:18 PM