2011-09-19 10 views
7

he levantado mi repositorio genérico de la siguiente manera:Cómo hacer repositorio genérico con la inyección de dependencias

public interface IRepository<T> : IDisposable where T : Entity 
{ 
    T GetById(int id); 
} 

public abstract class Repository<T> : IRepository<T> where T : Entity 
{ 
    protected readonly SqlDbContext _context = new SqlDbContext(); 

    public T GetById(int id) 
    { 
     return _context.Set<T>().Find(id); 
    } 
} 

Para permitir la inyección de dependencia en mi aplicación MVC yo también crear una interfaz del producto desde la firma difiere. Este es también el caso para los otros repositorios.

public interface IProductRepository : IRepository<Product> 
{ 
    IEnumerable<Product> GetDiscountedProducts(); 
} 

Y la aplicación (tenga en cuenta la herencia)

public class ProductRepository : Repository<Product>, IProductRepository 
{ 
    public IEnumerable<Product> GetDiscountedProducts() 
    { 
     return _context.Set<Product>().Where(x=>x)... 
    }   
} 

Finalmente el repositorio consigue inyecta en el controlador MVC usando la unidad

public HomeController(IProductRepository repository) 
{ 
} 

¿Soy yo o es esta cadena de herencia de una un poco sucio aquí? ¿Hay alguna forma de mejorar este diseño?

+0

Im pregunto lo que se gana por el 'Repositorio ' y 'IRepository ' patrón cuando se pasa como 'IProductRepository' - nunca verás la implementación 'Repository ' con eso a menos que lo hagas, por lo que es un poco inútil. – Tejs

+1

Eche un vistazo a esto: http://codebetter.com/gregyoung/2009/01/16/ddd-the-generic-repository/ – Dmitry

+0

¿Qué intenta lograr? (pregunta seria) Lo que tengo atm con mi proyecto MVC3 es 2 conjuntos de objetos (Consultas y Comandos ala CQRS), y cada uno de ellos viene con un LINQ que golpea una única clase Repository que tiene acceso a todos los objetos de la base de datos. ¿Dónde me beneficiaría tener múltiples repositorios en este caso?(Ya sé lo que cada Command/Query hace por su nombre de clase por convención) Y también, ¿dónde entra en juego la inyección de dependencia? Por el momento esto me parece demasiado ingenioso, pero estoy interesado en saberlo. –

Respuesta

6

sugeriría a evitar IProductRepository para este caso particular (cuando la simple adición de un método único y muy específico) y mejorar interfaz IRepository original como se muestra a continuación:

public interface IRepository<TEntity> : IDisposable 
       where TEntity : Entity 
{  
    TEntity GetById(int id); 
    IEnumerable<TEntity> List(IFilterCriteria criteria); 
} 

y luego implementar

public sealed class ProductDiscountFilterCriteria : IFilterCriteria 
{ 
    // ... 
} 

pero en tal caso debe definir alguna lógica para transformar los criterios en una consulta, podría ser una Expresión LINQ ya que usted ya está usando LINQ. Si ese enfoque de expresión de creteria es complejo para su caso, le sugiero que se quede con el enfoque que ha propuesto.

EDIT:IFilterCriteria es simplemente Query Object patrón de aplicación

interface IFilterCriteria<TQuery> 
{ 
    TQuery ToQuery(); 
} 

public sealed class ProductDiscountFilterCriteria : IFilterCriteria<DynamicExpression> 
{ 
    public decimal Discount { get; private set; } 

    public DynamicExpression ToQuery() 
    { 
    // build expression for LINQ clause Where("Discount" > this.Discount) 
    } 
} 

o criterios SQL prima constructor:

public sealed class ProductDiscountFilterCriteria : IFilterCriteria<string> 
{ 
    public decimal Discount { get; private set; } 

    public string ToQuery() 
    { 
    // simplified 
    return "WHERE Discount < " + this.Discount; 
    } 
} 

Así que allí tendría que ser capaz de utilizarlo como:

var products = productRepository.List<Product>(
          new DiscountFilterCriteria { Discount = 50 }); 

Dinámico ejemplos y artículos LINQ:

+0

¿Podría elaborar un poco el concepto de filtro con un ejemplo simple? – Fixer

+0

@Fixer: vea EDITAR parte de mi respuesta – sll

Cuestiones relacionadas