2013-03-31 92 views
1

我有一種情況使用存儲庫模式,我想有一些額外的存儲庫不對應任何實體。註冊派生的存儲庫立即實現接口

例如這裏是一個沒有:

public class TargetRepository : RepositoryBase<Target>, ITargetRepository 
{ 
    public TargetRepository(IDatabaseFactory databaseFactory) 
     :base(databaseFactory) 
    { 
    } 

      public IEnumerable<Target> GetValidTargets(){ ... } 
} 
public interface ITargetRepository : IRepository<Target> 
{ 
      IEnumerable<Target> GetValidTargets(); 
} 

Target是一個實體。

然後,我想有一些其他的存儲庫這樣的:

public class ScatterPlotRepositoryProxy : TargetRepository, IScatterPlotRepositoryProxy 
{ 
    public ScatterPlotRepositoryProxy(IDatabaseFactory databaseFactory) 
     :base(databaseFactory) 
    { } 

      public IEnumerable<ScatterPlotModel> GetSavedScatterPlots() { 
        this.GetValidTargets().Select(t => new ScatterPlotModel{ ... }); 
      } 
} 

public interface IScatterPlotRepositoryProxy 
{ 
     IEnumerable<ScatterPlotModel> GetSavedScatterPlots() 
} 

聲明本來自一個不TargetRepository如何RepositoryBase<Entity>繼承。這是因爲ScatterPlotModel不是一個實體,甚至沒有持續。但是,我想要另一層分離,以便我的TargetRespository不會因爲所有不同圖表類型的方法而變得混亂。

我還沒有實際執行這個,所以沒有錯誤呢。但我預見我的Autofac DI電話會在稍後導致問題,所以我提前詢問。

我該如何正確地使用Autofac註冊這些「存儲庫代理」?目前,我有這樣的:

builder.RegisterAssemblyTypes(typeof(TargetRepository).Assembly).Where(t => t.Name.EndsWith("Repository")).AsImplementedInterfaces().InstancePerApiRequest(); 

,加入這似乎是它會衝突:

builder.RegisterAssemblyTypes(typeof(TargetRepository).Assembly).Where(t => t.Name.EndsWith("RepositoryProxy")).AsImplementedInterfaces().InstancePerHttpRequest(); 

我會得到我所期望的行爲(IScatterPlotRepositoryProxy將解析爲ScatterPlotRepositoryProxyITargetRepository應該繼續,儘管解析到TargetRepositoryScatterPlotRepositoryProxy也從基礎知識庫中實現它)?

試圖從程序集中完成所有操作,以避免爲每個存儲庫添加行。

回答

3

您錯過了系統中的抽象。這會給你帶來各種麻煩和你已經目睹的痛苦。

您需要的是對系統中查詢的常見抽象。這消除了需要定製存儲庫接口。自定義存儲庫接口(如ITargetRepository)違反了五個原則中的三個,並且這 - 毫無疑問 - 導致各種可維護性問題。

我以前寫過一篇關於這個主題的文章,所以我不會在這裏重複一遍(讓我們保留它DRY),但是您一定要閱讀這篇文章:Meanwhile... on the query side of my architecture

在應用該文章給出的體系結構指導時,使用Autofac註冊存儲庫和查詢都不會有任何問題。這將是像下面這樣:

builder.RegisterAssemblyTypes(typeof(IRepository<>).Assembly) 
    .AsClosedTypesOf(typeof(IRepository<>)); 

builder.RegisterAssemblyTypes(typeof(IQueryHandler<,>).Assembly) 
    .AsClosedTypesOf(typeof(IQueryHandler<,>)); 
+0

這是一個很好的文章,你是一個非常熟練的程序員。它非常適合我現有的命令體系結構。現貨,謝謝! – parliament

+0

Btw不得不在您的答案中將'AsImplementedInterface()'添加到'IRepository <>'配置中以使其工作。再次感謝 – parliament

+0

@Vazgen:我根本不是一位有經驗的Autofac用戶,所以請隨時更新我的​​答案和更正。這也可以幫助其他開發者。 – Steven

相關問題