我知道接口不能定义构造函数。如何最好地强制所有实现接口的类在统一协议下接收其依赖项。我知道可以通过属性将依赖项注入对象,但是通过构造函数传递它们对我来说更有意义。那么如何进行依赖注入呢?
我知道接口不能定义构造函数。如何最好地强制所有实现接口的类在统一协议下接收其依赖项。我知道可以通过属性将依赖项注入对象,但是通过构造函数传递它们对我来说更有意义。那么如何进行依赖注入呢?
我知道你说过想要一份稳定的合同,但是不提供稳定接口的好处在于,你的依赖关系可能会随着不同实现而变化,这将降低耦合度:
public interface IBlogRepository
{
IEnumerable<Entry> GetEntries(int pageId, int pageCount);
}
class BlogDatabase : IBlogRepository
{
public BlogDatabase(ISession session)
{
this.session = session;
}
public IEnumerable<Entry> GetEntries(int pageId, int pageCount)
{
// Not that you should implement your queries this way...
var query = session.CreateQuery("from BlogEntry");
return query.Skip(pageId * pageCount).Take(pageCount);
}
private ISession session;
}
public interface IBlogRepository
{
ISession Session { get; set; }
IEnumerable<Entry> GetEntries(int pageId, int pageCount);
IEnumerable<Entry> GetEntriesWithSession(ISession session,
int pageId, int pageCount);
}
class BlogDatabase : IBlogRepository
{
public ISession Session { Get; set; }
public IEnumerable<Entry> GetEntries(int pageId, int pageCount)
{
var query = Session.CreateQuery ...
}
public IEnumerable<Entry> GetEntries(ISession session, int pageId, int pageCount)
{
var query = session.CreateQuery ...
}
}
class BlogFile : IBlogRepository
{
// ISession has to abstract a file handle. We're still okay
// ...
}
class BlogInMemory : IBlogRepository
{
// ISession abstracts nothing.
// Maybe a lock, at best, but the abstraction is still breaking down
// ...
}
public interface IInstallationFactory
{
IUser CreateRegisteredUser(Guid userSid);
IPackage CreateKnownPackage(Guid id);
IInstaller CreateInstaller();
}
许多框架也支持抽象工厂。
一种选择是在接口上创建一个初始化方法。该方法可以接受所有必需的依赖项。
类似于:
void Configure(dependency1 value, etc.);
当然,使用框架进行此类型的初始化和依赖注入有很多选择。但是有很多选项可供选择。
Scott Hanselman在这里列出了一个好的列表。
我们都知道这可以通过许多不同的方法实现,但是有意义的东西肯定更受欢迎。我定义了一些仅设置
属性,然后对象负责保存对传递给它的内容的引用:
public interface IBlogRepository
{
ISession Session { set; }
}
class BlogRepository : IBlogRepository
{
private ISession m_session;
ISession Session
{
set { m_session = value; }
}
}
这样,实现接口的每个类都知道set-only
属性是一个依赖注入,因为set-only
属性很少使用。我不确定这种方法是否被认为是一种良好的实践
,但对我来说,从现在开始是。