我正在构建一个允许用户上传扩展程序以扩展它的Web应用程序。扩展名是包含程序集的zip。我在AppDomain中加载程序集没有问题,我知道无法从AppDomain中删除程序集。
用户应该能够禁用或升级扩展程序。
我使用Autofac。
升级扩展程序后,我使用这种代码:
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterAssemblyModules(v2assembly);
builder.Update(container);
其中v2assembly
是包含模块的新程序集,该模块仅覆盖Load方法以注册其服务。
我的问题是,在升级扩展程序后,当我解析IEnumerable<IService>
时,容器会返回2个服务:一个来自 v1 程序集,另一个来自 v2 程序集。
不幸的是,我有一些要求:
我的应用程序可以使用容器在另一个需要时间的线程中解析的实例(不是来自任何扩展),例如,数据库导入操作。升级扩展不应该破坏这个长时间运行的操作;
我的应用程序使用单例实例,这些实例需要花费时间进行初始化,并且出于性能原因,扩展升级不应重置此单例;
应该替换的实例可以实现IDisposable,并且应该在升级过程中处理;
如果禁用扩展程序,则在解析特定类型时应使用运行时实现。
您有解决此问题的想法吗?
我的一个想法是使用元数据来注册来自扩展的类型,该元数据将指示扩展的版本然后实现IRegistrationSource,该IRegistrationSource将使用不是来自禁用扩展的实例。 我不知道如何做到这一点,以及这种注册资源会产生什么影响。
答案 0 :(得分:3)
答案很可能涉及在新的LifetimeScope
中注册新组件,并处理前一个组件。我不会更新现有的范围,因为那时原始的单身人士将继续存在。