2013-07-15 81 views
1

我有一個使用實體框架(DbContext)的共享庫。這個庫用於普通的Windows應用程序以及Web MVC項目中。我使用Ninject作爲DI。如何處理共享庫的不同Ninject作用域?

這是我的理解,我應該使用InThreadScopeDbContext Windows應用程序和InRequestScope爲MVC項目。

但是這會產生一些不需要的依賴關係。我的共享庫需要引用System.Web(用於請求範圍)。或者我的web項目需要EF的引用(所以我可以更改範圍)。

是否有可能以這種方式設置Ninject以避免這些依賴關係?

+0

所以我收集你的應用程序不直接需要的DbContext。什麼是它們使用DbContext的引用? – BatteryBackupUnit

+0

對不起,這是我想編輯我的評論(但被破壞):如果(線程/請求):Dependency:DbContext之間存在1:1:1的關係,您還可以在Dependency之間定義範圍約束: DbContext @共享庫和Thread:Dependency @ WinApp和Request:Dependency WebApp。這不需要任何額外的項目和參考。 但是,這隻有在涉及某種1:...:1 ...:1的情況下才有可能。 – BatteryBackupUnit

回答

0

我會建議創建一個新項目,如NinjectModules。將綁定聲明移入單獨的模塊,如WinAppModule,MvcModule並將其放入NinjectModules項目。然後從win app項目和mvc項目中參考NinjectModules。他們不需要再引用EF和System.Web

UPDATE

Modules diagram 你可以看到我的answer上類似的問題。

+0

兩個單獨的程序集,每行代碼1行?不要以爲我的身體會讓我輸入代碼。 – batkuip

+0

不,只需一個ninject模塊綁定聲明的附加程序集。 – mipe34

+0

我添加了圖表來幫助你理解。*請記住,你應該永遠不要在庫項目中聲明IOC綁定(庫的用戶應該決定使用哪個綁定,這樣你也將獨立於IOC容器實現上(依賴關係只會在頂層聲明)大多數項目)* – mipe34

0

行,所以我做了一個繪圖: moving the binding dependency to the intermediary 很多時候,一個使用「數據庫會話」之類的UnitOfWork的一定的代表性。 因此,如果您的共享庫「SomeLib」提供了IUnitOfWork來表示會話,那麼您可以在應用程序中創建1:1綁定IUnitOfWork:DbContext @ SomeLib和更具體的綁定。

+0

你是如何綁定接口的?或者你是否建議在UnitOfWork包裝中包裝DbContext?難道這不會有相同的問題嗎? – batkuip

+0

是的, m建議在UnitOfWork中包裝DbContext,只要UnitOfWork:IUnitOfWork的接口不包含與EF庫相關的任何東西,你就不需要引用它了,但是因爲我不是不熟悉EF我不知道是否適合這樣做。 – BatteryBackupUnit

0

又一可能的解決辦法是:

在SomeLib定義的DbContext的結合如下:

this.Bind<DbContext>().ToSelf() 
    .InScope(ctx => ctx.Kernel.Get<IDbContextScopeRetriever>().Retrieve());` 

using a scope retriever 然後創建和綁定的IDbContextScopeRetriever各實施方式在應用程序中。

ThreadDbContextScopeRetriever實現可能是:

object Retrieve() { 
    return System.Threading.Current; 
} 
+0

我試過類似的東西,將範圍lamba直接傳遞給NinjectModule。這工作正常,除了InRequestScope的範圍lamba是私人的。 Ofc我可以拆除實施,但這種破解破壞了目的。 – batkuip

+0

是的,你是絕對正確的。我不知道InRequestScope有多複雜(github web目前無法訪問),所以我認爲它可能比有不需要的引用更糟糕。 (InThreadScope非常簡單,如答案所示)。 – BatteryBackupUnit

相關問題