我知道接口(interface)不能定义构造函数。强制所有实现接口(interface)的类在统一契约中接收它们的依赖项的最佳实践是什么。我知道整数可以通过属性将依赖项注入(inject)对象,但通过构造函数传递它们对我来说更有意义。那怎么DI呢?
最佳答案
我知道你说过你想要一份稳定的契约(Contract)。但是不提供稳定接口(interface)的一个优点是您的依赖项可能会随着不同的实现而发生巨大变化,这将减少耦合:
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;
}
如您所说,您还可以将依赖项作为属性(或参数)来实现,但这将对您的依赖项进行硬编码,而不是使它们成为特定于实现的。您将分离您的特定 session 实现,但您仍然必须依赖于 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
// ...
}
构造函数注入(inject)只有在您使用某种可以为您处理构建/提供依赖项的依赖注入(inject)框架时才有效。即使没有框架,属性和参数注入(inject)也能正常工作。
我相信这三个都是公认的做法。至少有几个流行的框架同时支持构造函数和属性注入(inject)。
这意味着您可以决定什么对您的项目最有意义。权衡是一个易于追踪的依赖图,而不是更强的耦合。该决定当然也不必是全构造函数或全属性/参数。
要考虑的另一个更高级别的抽象是抽象工厂类。如果你想对一组依赖项进行分组,或者你需要在运行时构建它们的实例,你会这样做:
public interface IInstallationFactory
{
IUser CreateRegisteredUser(Guid userSid);
IPackage CreateKnownPackage(Guid id);
IInstaller CreateInstaller();
}
各种框架也支持抽象工厂。
关于c# - 如何将依赖项注入(inject)实现接口(interface)的类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4115453/