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

问题描述

| 我正在使用Entity Framework构建存储库基类,所有Entities存储库都将继承该基类。我想使用Ninject使用依赖注入在基类中注入ѭ0。我认为构造函数注入是正确的方法,但是在派生类中使用构造函数注入进行此操作,我必须将参数传递给基类中的构造函数,而我不希望这样做。因此,Setter注入是否更合适? 这是我的代码:
public abstract class BaseRepository<TEntity> : IDisposable 
    where TEntity : class
{
    private readonly DatabaseContext _databaseContext;

    protected BaseRepository(DatabaseContext databaseContext)
    {
        this._databaseContext = databaseContext;
    }
}
在上面的示例中使用构造函数注入,在派生类中,我必须将databaseContext对象传递给基类,我不希望对所有派生类都这样做:
public class UsuarioRepository : BaseRepository<IUsuario>,IUsuarioRepository
{
    public UsuarioRepository(DatabaseContext databaseContext)
        : base(databaseContext)
    {
    }
}
用setter注入代替构造函数注入是解决此问题的好方法吗?什么是最好的方法? 更新: 使用Setter Injection,我的派生类将没有构造函数:
public class UsuarioRepository : BaseRepository<IUsuario>,IUsuarioRepository
{
}
我的上下文只是所有应用程序中的一个。我不需要派生类来传递上下文对象,但我希望将其注入基类中,以便将来使用模拟进行测试。 我解决了这个问题: 抱歉,我对此问题感到困惑,但是我正在解决建立工厂的问题:
public abstract class BaseRepository<TEntity> : IBaseRepository<TEntity>
   where TEntity : class
{
    private readonly ContextFactory _contextFactory = new ContextFactory();

    protected DatabaseContext CurrentContext
    {
        get
        {
            return this._contextFactory.GetCurrentContext();
        }
    }
 }
我的派生类如下所示:
public class UsuarioRepository : BaseRepository<IUsuario>,IUsuarioRepository
{
}
我的工厂就像这样:
public class ContextFactory
{
    public DatabaseContext GetCurrentContext()
    {
        return new DatabaseContext();
    }
}
    

解决方法

属性注入意味着依赖关系是可选的,而构造函数注入意味着依赖关系是必需的。相应地选择一种模式。 在超过95%的情况下,构造函数注入是正确的模式。那你不喜欢吗?     ,我认为没有“最佳方法”。 构造函数和setter注入并不完全等效,因为setter注入为您提供了更多的灵活性。这是我在两者之间进行选择的方式: 假设您创建了一个对象A,而A需要一个B对象才能工作。要问的问题是:A是否可能存在/被实例化而不与B关联? A对象没有B是否是有效状态?有时,对于A来说,拥有一个空B毫无意义,那么构造函数注入是更好的解决方案。如果以后可以将B分配给A,而不必在构造时分配给A,则可以使用二传手注入。所有这一切都取决于您要建模的领域,答案会因情况而异。     ,真的,我看不到将参数传递给基类的任何问题。但是,如果这是绝对要求,则可以始终这样做:
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是必需的依赖项。对于所需的依赖关系,请进行构造函数注入。如果是可选的,则一定要继续进行二传手进样。 编辑: 由于我们在评论中进行了长时间的交谈,因此我对您要完成的工作有了更好的理解。 如果要将派生类与DatabaseContext分离,最好进行不同的设计。很难将派生类与其基类的依赖项分离,如果您认为应该将它们分离,那么您将有更好的设计,根本不用继承。
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的基类,并且派生类不再依赖于它。     ,所有三种方式1.构造器,2。设置器和3.接口注入有其优缺点,取决于使用情况。如果我会在您的位置,尽管接口也可以是一个不错的选择,但我会选择二传手。 要求您阅读本文 http://www.devx.com/dotnet/Article/34066     

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...