asp.net-mvc - unit - patron repositorio net core
Patrón de repositorio: ¿Una clase de repositorio para cada entidad? (4)
Digamos que tienes las siguientes entidades definidas en una clase LINQ:
Product
Customer
Category
Debería tener una clase de repositorio para todos:
StoreRepository
... o debería tener:
ProductRepository
CustomerRepository
CategoryRepository
¿Cuáles son las ventajas y desventajas de cada uno? En mi caso, tengo varias "aplicaciones" dentro de mi solución ... la aplicación Store es solo una de ellas.
Aquí está mi punto de vista. Soy un seguidor estricto del patrón Repositorio. Debería haber 3 métodos que tomen una sola entidad. Añadir, actualizar, eliminar, genéricamente definido.
public interface IRepository<T>
{
void Add(T entity);
void Update(T entity);
void Delete(T entity);
}
Más allá de esos métodos, estás tratando con una "Consulta" o un método de servicio. Si fuera usted, haría que el repositorio se definiera genéricamente como se mencionó anteriormente, agregue un "Proveedor de consultas" como se muestra a continuación y coloque su lógica de negocios donde pertenezca a "Servicios" o a "Comandos / Consultas" (proviene de CQRS, Google es) .
public interface IQueryProvider<T>
{
TResult Query<TResult>(Func<IQueryable<T>, TResult> query);
}
(Espero que mi opinión sea algo útil :))
Básicamente habrá un repositorio por objeto raíz agregado. Hay algunos puntos interesantes sobre DDD
y el objeto raíz agregado y sobre cómo deberíamos diseñar clases de repositorio en el libro ASP.NET MVC 2 en Acción . Mírelo si desea saber más.
Tendría un repositorio / objeto porque, invariablemente, tendría que haber un mapa de mi EntityTable a mi objeto de dominio (como en el cuerpo de GetIQueryableCollection (). Cómo me las arreglé para escribir este código repetitivo es hacer un Plantilla T4 para generarlo por mi.
Tengo un proyecto de ejemplo que genera el patrón de repositorio en codeplex http://t4tarantino.codeplex.com/ Ejemplo de T4 Toolbox Plantillas para clases de negocio y repositorio. Es posible que no funcione exactamente de la manera que le gustaría sin algunos ajustes, a menos que ya esté implementando Tarintino y algunos otros beneficios, pero las plantillas son fáciles de configurar.
using System;
using System.Collections.Generic;
using System.Linq;
using Cses.Core.Domain.Model;
using StructureMap;
namespace Cses.Core.Domain
{
/// <summary>
/// Core class for Schedule E
/// </summary>
public class ScheduleERepository : IScheduleERepository
{
private Cses.Core.Repository.SqlDataContext _context = new Cses.Core.Repository.SqlDataContext();
/// <summary>
/// constructor
/// </summary>
public ScheduleERepository() { }
/// <summary>
/// constructor for testing
/// </summary>
/// <param name="context"></param>
public ScheduleERepository(Cses.Core.Repository.SqlDataContext context)
{
_context = context;
}
/// <summary>
/// returns collection of scheduleE values
/// </summary>
/// <returns></returns>
public IQueryable<ScheduleE> GetIQueryableCollection()
{
return from entity in _context.ScheduleEs
select new ScheduleE()
{
Amount = entity.Amount,
NumberOfChildren = entity.NumberChildren,
EffectiveDate = entity.EffectiveDate,
MonthlyIncome = entity.MonthlyIncome,
ModifiedDate = entity.ModifiedDate,
ModifiedBy = entity.ModifiedBy,
Id = entity.Id
};
}
Todo esto depende de cómo va a ser "Diseño impulsado por dominio". ¿Sabes lo que es una raíz agregada? La mayoría de las veces, un código genérico puede hacer todo su CRUD básico será suficiente. Solo cuando comienzas a tener modelos gruesos con contexto y límites, esto comienza a importar.