我有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)
{
// ...
}
}
我可以避免不得不从C中引用B,通过使用扫描&加载可用的程序集并使b.d dll在运行时可用,很容易。但是,我如何提供构造器参数的蒙古收集工厂没有这些细节泄漏到C?此外,C需要连接到不同数据库的ICollectionFactory的多个实例,并且这些实例需要绑定到C中的正确服务。
我已经看了Ninject和LightInject到目前为止。我很高兴使用任何成熟的容器,在Mono上工作,至少有合理的性能。
编辑
我创建了另一个程序集;组合根'D'引用其他所有东西。该组件和入口点程序集是引用DI容器的唯一组件。D也有系统的配置(连接细节、端点等)。我对这个解决方案很满意,尽管我认为随着系统的发展,D会变成一个怪物。
您在这里缺少的是组合根的概念。换句话说,您缺少的是一个启动程序集,它引用所有其他程序集并将所有内容连接在一起。
如果您的C-Service需要两个不同的数据库,则需要在其构造函数中使用两个参数。
示例:如果服务必须将数据从源icollectionfactory复制到目标icollectionfactory,那么构造函数将是这样的。
public class AService(ICollectionFactory source, ICollectionFactory destination)
{ ... }
通常你需要一个单独的模块"D",它负责连接所有依赖项,并知道数据库特定的设置。