2011-09-19 12 views
7

mam skonfigurować rodzajowe repozytorium w następujący sposób:Jak zrobić Generic repozytorium z Dependency Injection

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); 
    } 
} 

Aby włączyć iniekcji zależność w mojej aplikacji MVC i również utworzyć interfejs produktu, ponieważ podpis różni. Dotyczy to również innych repozytoriów.

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

i wdrożenie (nota dziedziczenia)

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

Wreszcie repozytorium zostaje wstrzyknięty do kontrolera MVC przy użyciu jedność

public HomeController(IProductRepository repository) 
{ 
} 

Czy to tylko mnie czy jest to dziedziczenie łańcuch trochę tu brudny? Czy istnieje sposób na ulepszenie tego projektu?

+0

Im zastanawiasz się, co uzyskuje się przez 'Repozytorium ' i 'IRepository ' wzór kiedy jest przekazywana jako 'IProductRepository' - nigdy nie zobaczysz implementacji 'Repository ', chyba że użyjesz rzutowania, więc jest to trochę bezużyteczne. – Tejs

+1

Spójrz na to: http://codebetter.com/gregyoung/2009/01/16/ddd-the-generic-repository/ – Dmitry

+0

Co ta próba osiągnięcia? (poważne pytanie) Co mam atm z moim projektem MVC3 to 2 zestawy obiektów (Zapytania i komendy ala CQRS), a każdy z nich ma LINQ, który uderza w pojedynczą klasę Repository, która ma dostęp do wszystkich obiektów bazy danych. Gdzie w takim przypadku korzystanie z wielu repozytoriów byłoby dla mnie korzystne?(Wiem już, co każde polecenie/zapytanie wykonuje według nazwy klasy zgodnie z konwencją) A także, skąd bierze się wtrysk zależności? W tej chwili wydaje mi się to zbytnio przesadzone, ale chcę wiedzieć. –

Odpowiedz

6

sugeruję uniknąć IProductRepository dla tego konkretnego przypadku, (po prostu dodając sposób jednolity, specyficzny) i zwiększenie pierwotnej IRepository interfejs, jak pokazano poniżej:

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

a następnie realizować

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

ale w takim przypadku musisz zdefiniować jakąś logikę, aby przekształcić kryteria do zapytania, może to być wyrażenie LINQ, ponieważ już używasz LINQ. Jeśli takie podejście do wyrażania kreacji jest skomplikowane w twoim przypadku - sugerowałbym pozostać przy podejściu, które zaproponowałeś.

EDIT:IFilterCriteria jest po prostu Query Object wzór realizacja

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) 
    } 
} 

lub surowe kryteria SQL budowniczy:

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

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

Tak więc będzie można z niego korzystać jak:

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

Dynamic przykłady LINQ i artykuły:

+0

Czy możesz nieco rozwinąć koncepcję filtra za pomocą prostego przykładu? – Fixer

+0

@Fixer: zobacz EDIT część mojej odpowiedzi – sll

Powiązane problemy