Digamos que tengo un patrón de repositorio siguiente:
interface IGenericRepo<T> where T : class { IEnumerable<T> GetAll(); T GetById(object id); void Insert(T obj); void Update(T obj); void Delete(T obj); void Save(); } interface ICustRepo : IGenericRepo<Cust> { IEnumerable<Cust> GetBadCust(); IEnumerable<Cust> GetGoodCust(); } public class CustRepo : ICustRepo<Cust> { //implement method here }luego en mi controlador:
public class CustController { private ICustRepo _custRepo; public CustController(ICustRepo custRepo) { _custRepo = custRepo; } public ActionResult Index() { var model = _custRepo.GetAll(); return View(model); } public ActionResult BadCust() { var model = _custRepo.GetBadCust(); return View(model); } }Básicamente mi patrón es algo así como
View <-> Controller -> Repo -> EF -> SQL Server
pero vi a mucha gente haciendo esto
View <-> Controller -> Service -> Repo -> EF -> SQL Server
Entonces mi pregunta es:
¿Por qué y cuándo necesito service layer ? ¿No es solo agregar otra capa innecesaria porque todos los métodos no genéricos ya están implementados en ICustRepo ?
¿Debería la capa de servicio devolver DTO o mi ViewModel ?
¿Debería la capa de servicio mapear 1:1 con mi repositorio?
He mirado a mi alrededor durante unos días, pero no estoy satisfecho con las respuestas.
Cualquier ayuda será apreciada y se disculpa por el mal inglés.
Gracias.
ACTUALIZAR :
¿Diferencia entre repositorio y capa de servicio?
Ya he leído esto. Ya sé la diferencia entre esos 2, pero quiero saber por qué y el propósito. entonces eso no responde mi pregunta
TL;DR
Explicación
La arquitectura típica de 3 capas se compone de capa de presentación, capa de servicio/dominio, capa de acceso a datos (DAL).
Piense en la capa de servicio como el "núcleo" de su aplicación. Por lo general, la capa de servicio solo tiene interfaces de repositorio que se implementarán en la DAL.
Por lo tanto, le permite cambiar "fácilmente" la forma en que accede a los datos. Los objetos devueltos por la capa de servicio no deberían ser DAO, porque después de todo, la capa de presentación ni siquiera "sabe" que existe DAL.
Escenario: Tiene una Solución de 3 niveles. Actualmente no tiene mucho sentido tener todas las capas.
/-------------------\ | Web App | <--- Presentation Layer |-------------------| | Service Library | <--- Service Layer |-------------------| | Entity Framework | <--- Data Access \-------------------/Ahora quiere tener una API REST en ASP.NET MVC WebApi
/--------------------\ | Web App | REST API | <--- Presentation Layer |--------------------| | Service Library | <--- Service Layer |--------------------| | Entity Framework | <--- Data Access \--------------------/Ahora, por ejemplo, ya no quiere usar Entity Framework como su acceso a datos y quiere usar NHibernate.
/--------------------\ | Web App | REST API | <--- Presentation Layer |--------------------| | Service Library | <--- Service Layer |--------------------| | NHibernate | <--- Data Access \--------------------/Tenga en cuenta que agregamos una nueva forma de presentación y cambiamos la forma en que accedemos a los datos, pero la capa de servicio nunca cambió.
Por lo general, la capa de servicio expone las interfaces que se implementarán en la capa de acceso a datos para que obtengamos la "abstracción" que queremos.
Implementé un proyecto con esta arquitectura en la universidad. Puedes consultar el código AQUÍ
Espero que esto haya ayudado. Lo siento si soy tan aburrido explicando cosas :P
Ad.1 La capa de servicio debe tener lugar para toda la lógica empresarial. Se trata más de responsabilidades separadas:
Controlador - responsable de preparar viewModel y pasar a la vista específica,
Repositorio: capa abstracta responsable de recopilar entidades de DB
Servicio: responsable de la lógica compleja. A menudo hay casos en que el servicio usa muchas entidades para hacer algo de lógica y devolver solo DTO.
Ad.2 En mi opinión, la capa de servicio debería devolver objetos DTO que deberían asignarse a los modelos de vista en los controladores.
Ad.3 No, este no es el caso. En su ejemplo, puede mover GetBadCust y GetGoodCust del repositorio al servicio y devolver algo de DTO