如何避免引用带有实现细节的程序集



我有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",它负责连接所有依赖项,并知道数据库特定的设置。

最新更新