2011-09-19 23 views
7

設置我的通用倉庫如下:我也怎麼做通用庫與依賴注入

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

爲了使依賴注入在我的MVC應用程序,我也創建一個產品的接口,因爲簽名不同。其他儲存庫也是如此。

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

和實現(注意繼承)

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

最後的版本庫使用統一

public HomeController(IProductRepository repository) 
{ 
} 

注入到MVC控制器難道只是我,或者這是繼承鏈有點凌亂在這裏?有什麼方法可以改進這種設計嗎?如下所示

+0

我想知道是什麼的'庫'和'IRepository 獲得'當它爲'IProductRepository'真實傳遞模式 - 你永遠不會看到'Repository '的實現,除非你投了,所以它有點沒用。 – Tejs

+1

看看這個:http://codebetter.com/gregyoung/2009/01/16/ddd-the-generic-repository/ – Dmitry

+0

這是試圖達到什麼目的? (嚴重問題) 我的MVC3項目有兩組對象(查詢和命令ala CQRS),並且每個對象都帶有一個LINQ,它可以訪問可以訪問所有數據庫對象的單個Repository類。 在這種情況下,有多個存儲庫會讓我受益?(我已經知道每個命令/查詢通過其約定的類名稱) 而且,依賴注入在哪裏起作用? 目前這看起來像對我過度工程,但我有興趣知道。 –

回答

6

我建議避免IProductRepository對於這種特殊情況下(簡單地添加單和非常特定的方法時),增強原IRepository接口:

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

,然後實現

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

但在這種情況下,您必須定義一些邏輯來將條件轉換爲查詢,因爲您已經在使用LINQ,所以它可能是LINQ表達式。如果這種表達方式對您的案例來說很複雜 - 我會建議堅持您提出的方法。

編輯:IFilterCriteria簡直是Query Object模式實現

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

或原始SQL標準建造:

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

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

,那麼你將能夠使用它像:

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

動態LINQ的例子和文章:

+0

你能用一個簡單的例子來詳細闡述Filter概念嗎? – Fixer

+0

@Fixer:參見我的答案的編輯部分 – sll