簡體   English   中英

基礎 Class 中的構造函數依賴注入

[英]Constructor Dependency Injection in Base Class

我正在使用實體框架構建一個存儲庫庫 class,所有實體存儲庫都將繼承。 我想使用 Ninject 的依賴注入將DatabaseContext注入基礎 class 中。 我認為構造函數注入是正確的方法,但是在派生的 class 中使用構造函數注入來執行此操作,我必須將參數傳遞給基礎 class 中的構造函數,我不想要它。 因此,Setter 注入更合適?

這是我的代碼:

public abstract class BaseRepository<TEntity> : IDisposable 
    where TEntity : class
{
    private readonly DatabaseContext _databaseContext;

    protected BaseRepository(DatabaseContext databaseContext)
    {
        this._databaseContext = databaseContext;
    }
}

Using Constructor Injection in the above example, in my derived class I will must to pass databaseContext object to base class, I don't like to doing this to all my derived class :

public class UsuarioRepository : BaseRepository<IUsuario>,
    IUsuarioRepository
{
    public UsuarioRepository(DatabaseContext databaseContext)
        : base(databaseContext)
    {
    }
}

Setter Injection 而不是 Constructor Injection 是解決這個問題的好方法嗎? 什么是最好的方法?

更新:

使用 Setter Injection 我的派生類將沒有構造函數:

public class UsuarioRepository : BaseRepository<IUsuario>, IUsuarioRepository
{
}

我的上下文只是所有應用程序中的一個。 我不需要派生的 class 來傳遞上下文 object,但我喜歡將其注入基礎 class 以在未來使用模擬進行測試。

我解決問題:

抱歉,我對這個問題感到困惑,但我正在解決我建立工廠的問題:

public abstract class BaseRepository<TEntity> : IBaseRepository<TEntity>
   where TEntity : class
{
    private readonly ContextFactory _contextFactory = new ContextFactory();

    protected DatabaseContext CurrentContext
    {
        get
        {
            return this._contextFactory.GetCurrentContext();
        }
    }
 }

我派生的 class 看起來像這樣:

public class UsuarioRepository : BaseRepository<IUsuario>, IUsuarioRepository
{
}

我的工廠就是這樣:

public class ContextFactory
{
    public DatabaseContext GetCurrentContext()
    {
        return new DatabaseContext();
    }
}

屬性注入意味着依賴是可選的,而構造函數注入意味着依賴是必需的。 相應地選擇一種模式。

在超過 95% 的情況下,構造函數注入是正確的模式。 不喜歡怎么辦?

我認為沒有“最好的方法”。

構造函數和 setter 注入並不完全等價,因為 setter 注入為您提供了更多的靈活性。 以下是我如何在兩者之間進行選擇:

假設您創建了一個 object A,而 A 需要一個 B object 才能工作。 要問的問題是:A 是否有可能存在/被實例化而沒有與之關聯的 B? A object 沒有 B 是有效的 state 嗎? 有時 A 擁有 null B 是沒有意義的,那么構造函數注入是更好的解決方案。 如果可以稍后將 B 分配給 A,而不必在構建時分配,則 go 與 setter 注入。 所有這一切都取決於您嘗試 model 的域,並且答案會因情況而異。

真的,我看不出將參數傳遞給基本 class 有任何問題。 但如果這是絕對要求,你總是可以這樣做:

 public abstract class BaseRepository<TEntity>: IDisposable where TEntity: class { protected BaseRepository() { } protected abstract DatabaseContext GetContext(); }

現在您的派生類可能如下所示:

 public class UsuarioRepository: BaseRepository<IUsuario>, IUsuarioRepository { private DatabaseContext _databaseContext; public UsuarioRepository(DatabaseContext databaseContext) { _databaseContext = databaseContext; } protected override DatabaseContext GetContext() { return _databaseContext; } }

現在您可以在不向基本構造函數傳遞參數的情況下進行構造函數注入。 但這真的是一回事。

老實說,我不喜歡 setter 注入的想法,因為看起來 DatabaseContext 是必需的依賴項。 對於所需的依賴項,進行構造函數注入。 如果它是可選的,那么一定要提前 go 並進行 setter 注入。

編輯:

由於我們在評論中進行了長時間的交談,我對您要完成的工作有了更好的理解。

如果您想將派生類與 DatabaseContext 分離,最好以不同的方式設計它。 很難將派生的 class 與其基類的依賴關系解耦,如果您認為它們應該解耦,那么您將有更好的設計,根本不使用 inheritance。

 public class BaseRepository<TEntity>: IDisposable where TEntity: class { public BaseRepository(DatabaseContext context) { } }

現在您的派生類(不再派生)將如下所示:

 public class UsuarioRepository: IUsuarioRepository { public UsuarioRepository(BaseRepository<IUsario> repository) { } // Implement other methods here }

現在您可以擁有一個使用 DatabaseContext 的基礎 class,並且您的派生類不再依賴它。

這三種方式1.構造器,2.Setter和3.接口注入都有其優點和缺點,取決於使用哪一種情況。 如果我在你的位置,我會選擇 setter,盡管界面也是一個不錯的選擇。

通過本文請求您 go http://www.devx.com/dotnet/Article/34066

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM