问题描述
|
我正在使用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