如何向动态加载的程序集注入依赖项

7
我有一个管理器类,通过反射加载包含在不同程序集中的各种插件模块。这些模块是与外界通信的(WebAPI、其他各种网络协议)。
public class Manager
{
   public ILogger Logger; // Modules need to access this.

   private void LoadAssemblies()
   {
     // Load assemblies through reflection.
   }
}

这些插件模块必须与管理类中包含的对象进行通信。我如何实现这一点?我考虑使用依赖注入/IoC容器,但如何跨程序集进行操作呢?
另一个想法是让插件模块引用包含所需资源的静态类,但我并不太满意。
欢迎提出建设性的评论和建议。

你如何实例化这些插件的实例?它们是否实现了一个或多个接口? - qujck
1个回答

1

大多数IOC容器都应该支持这个功能。例如,使用Autofac,您可以这样做:

// in another assembly
class plugin {
   // take in required services in the constructor
   public plugin(ILogger logger) { ... }
}

var cb = new ContainerBuilder();

// register services which the plugins will depend on
cb.Register(cc => new Logger()).As<ILogger>();

var types = // load types
foreach (var type in types) {
    cb.RegisterType(type); // logger will be injected
}

var container = cb.Build();
// to retrieve instances of the plugin
var plugin = cb.Resolve(pluginType);

根据您的应用程序如何调用插件,您可以适当地更改注册方式(例如,使用AsImplementedInterfaces()进行注册以通过已知接口检索插件,或使用Keyed通过某些关键对象(例如字符串)检索插件)。


我该如何使用Ninject来实现这个? - joek1975
@ChaseMedallion,我有一个问题。我的类负责加载程序集并注入它们的所有依赖项,这个类位于一个隔离的库中。这个库通过构造函数注入了所有的依赖项。IoC容器位于我的消费者应用程序中(消费者应用程序甚至可能没有使用容器!)。那么,我如何在不访问容器的情况下,潜在地注入动态加载对象的所有依赖项,而不需要从构造函数中显式请求每个依赖项?MEF是答案吗? - Vin Shahrdar
@ShervinShahrdar 通常情况下,使用控制反转模式时,您希望在顶层(即消费者应用程序)将所有内容连接在一起。较低级别的库要么具有容器感知能力,要么没有(虽然您可以通过依赖于类似于 System.IServiceProvider 的通用容器接口来达到中间位置)。一般来说,如果您有一个试图执行IOC风格的注册和连接的库,通常最好是使该库了解容器。对于Autofac,"模块"的概念为库源的注册和设置提供了一种自然的方法。 - ChaseMedallion

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接