我有3个库,A,B和C.A定义了持久性库契约,B使用MongoDb实现C,C仅引用A。我想将B注入C而不泄漏任何特定于B的内容。
考虑
namespace A
{
public interface ICollectionFactory
{
ICollection<T> GetCollection<T>();
}
}
using A;
namespace B
{
public class MongoCollectionFactory : ICollectionFactory
{
public CollectionFactory(string host, string db, int port)
{
// < init readonly fields >
}
public ICollection<T> GetCollection<T>(){ ... }
}
}
using A;
namespace C
{
public class AService(ICollectionFactory collectionFactory)
{
// ...
}
}
我可以避免使用扫描和扫描的DI库中的各种技术从C引用B.加载可用的程序集并在运行时使B.dll可用,很简单。但是如何在没有这些细节泄漏到C的情况下为MongoCollectionFactory提供构造函数参数?此外,C需要连接到差异数据库的多个ICollectionFactory实例,这些实例需要绑定到C中的正确服务。
到目前为止,我看过Ninject和LightInject。我很高兴使用任何适用于Mono的成熟容器,并且至少具有合理的性能。
修改
我创造了另一个集会;作文根&#39; D&#39;它引用了其他一切。这和入口点组件是唯一引用DI容器的组件。 D还具有系统配置(连接详细信息,端点等)。我对这个解决方案感到满意,尽管随着系统的发展我可以看到D变成怪物。
答案 0 :(得分:1)
如果您的C-Service需要两个不同的数据库,则在其构造函数中需要两个参数。
示例:如果服务必须将数据从source-ICollectionFactory复制到destination-ICollectionFactory,那么构造函数将如下所示。
public class AService(ICollectionFactory source, ICollectionFactory destination)
{ ... }
通常你需要一个单独的模块“D”,它负责连接所有依赖项并知道特定于数据库的设置。
答案 1 :(得分:1)
你在这里遗漏的是Composition Root的概念。换句话说,您缺少的是一个引用all other assemblies并将所有内容连接在一起的启动程序集。