基类中的构造函数依赖注入

Aca*_*uza 10 .net c# dependency-injection inversion-of-control

我正在使用Entity Framework构建存储库基类,其中所有实体存储库都将继承.我想DatabaseContext使用Ninject使用Dependency Injection 注入in基类.我认为构造函数注入是正确的方法,但在派生类I中使用构造函数注入执行此操作必须将参数传递给基类中的构造函数,我不想要它.因此,Setter Injection更合适吗?

这是我的代码:

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

    protected BaseRepository(DatabaseContext databaseContext)
    {
        this._databaseContext = databaseContext;
    }
}
Run Code Online (Sandbox Code Playgroud)

在上面的例子中使用构造函数注入,在我的派生类中,我必须将databaseContext对象传递给基类,我不喜欢对我的所有派生类执行此操作:

public class UsuarioRepository : BaseRepository<IUsuario>,
    IUsuarioRepository
{
    public UsuarioRepository(DatabaseContext databaseContext)
        : base(databaseContext)
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

Setter Injection而不是Constructor Injection是解决这个问题的好方法吗?什么是最好的方法?

更新:

使用Setter Injection我的派生类不会有构造函数:

public class UsuarioRepository : BaseRepository<IUsuario>, IUsuarioRepository
{
}
Run Code Online (Sandbox Code Playgroud)

我的上下文只是所有应用程序中的一个.我不需要派生类来传递上下文对象,但是我想将它注入基类中以便将来使用模拟测试.

我解决了这个问题:

对不起,我对这个问题感到困惑,但是我正在解决建立工厂的问题:

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

    protected DatabaseContext CurrentContext
    {
        get
        {
            return this._contextFactory.GetCurrentContext();
        }
    }
 }
Run Code Online (Sandbox Code Playgroud)

我的派生类看起来像这样:

public class UsuarioRepository : BaseRepository<IUsuario>, IUsuarioRepository
{
}
Run Code Online (Sandbox Code Playgroud)

和我的工厂那样:

public class ContextFactory
{
    public DatabaseContext GetCurrentContext()
    {
        return new DatabaseContext();
    }
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*ann 18

Property Injection意味着依赖项是可选的,而Constructor Injection意味着需要依赖项.相应地选择一种模式.

在95%以上的情况下,构造函数注入是正确的模式.你不喜欢它怎么样?

  • @Acaz Souza:是的,他们需要那个,因为依赖是*必需*.由于需要依赖性,让编译器强制执行此不变量是一件好事. (6认同)
  • 我不喜欢在我的派生类中将参数传递给基类,使用setter注入不会发生这种情况. (4认同)
  • @Acaz问题在于,如果`BaseRepository <TEntity>`需要一个`DatabaseContext`实例来运行,它就是一个依赖项,你不应该允许基类的实例用无效状态实例化.构造函数用于创建应该可用的类型的实例.使用设置注入只是引入开发人员需要准确知道他们需要将`DatabaseContext`设置为类型初始化中的附加步骤.对于开发者来说,理想情况下不是最好的事情 简单,如果是依赖项,请使用构造函数注入. (4认同)
  • 除了@Acaz个人偏好之外,构造函数注入确实是适用于您的场景的唯一合适的解决方案. (2认同)

Abh*_*nia 3

我认为没有“最好的方法”。

构造函数和 setter 注入并不完全等同,因为 setter 注入为您提供了更多的灵活性。以下是我在两者之间进行选择的方法:

假设您创建了一个对象 A,而 A 需要一个 B 对象才能工作。要问的问题是:A 是否可以在没有与之关联的 B 的情况下存在/被实例化?A 对象没有 B 是有效状态吗?有时,A 拥有 null B 是没有意义的,那么构造函数注入是更好的解决方案。如果 B 可以稍后分配给 A,而不一定是在构造时,那么就使用 setter 注入。所有这些都取决于您尝试建模的领域,并且答案会因情况而异。