当前位置:  开发笔记 > 编程语言 > 正文

如何在不使用AppDomains的情况下实现.net插件?

如何解决《如何在不使用AppDomains的情况下实现.net插件?》经验,为你挑选了1个好方法。

问题陈述:实现一个插件系统,允许覆盖关联的程序集(避免文件锁定).在.Net中,可能无法卸载特定程序集,只能卸载整个AppDomain.

我发布这个是因为当我试图解决问题时,每个解决方案都参考了使用多个AppDomain.即使在项目开始时进行架构,多个AppDomain也很难正确实现.

此外,AppDomains对我不起作用,因为我需要跨域传输Type作为Speech Server worfklow的InvokeWorkflow活动的设置.不幸的是,跨域发送类型会导致程序集注入本地AppDomain.

此外,这与IIS相关.IIS具有卷影复制设置,允许执行程序集在加载到内存时被覆盖.问题是(至少在XP下,没有在生产2003服务器上测试)当您以编程方式加载程序集时,卷影副本不起作用(因为您正在加载DLL,而不是IIS).



1> Abtin Forouz..:

    检查组件是否已加载(以避免因反复加载同一组件而导致内存泄漏).

    如果未加载,请将程序集读入字节数组.这样可以防止锁定文件.

    将字节数组作为Assembly.Load的争论提供

以下代码假定您知道程序集的FullName.

Assembly assembly = null;

foreach(Assembly loadedAssembly in AppDomain.CurrentDomain.GetAssemblies())
    if (loadedAssembly.FullName == "foobar, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
        assembly = loadedAssembly;

if(assembly == null)
{
    byte[] studybin = System.IO.File.ReadAllBytes(@"C:\pathToAssembly\foobar.dll");
    assembly = Assembly.Load(studybin);                
}

请注意,如果您尝试在目录中查找特定程序集,则可以运行"System.Reflection.AssemblyName.GetAssemblyName(path);" 查看FullName是否与您要查找的内容相匹配.'GetAssemblyName(path)'不会将程序集注入当前的AppDomain.

另请注意,此解决方案不适用于必须很少重新启动并且程序集以高频率更改的应用程序.每次加载程序集时,应用程序的内存占用量都会增加.没有方法可以卸载程序集,因此缩小内存使用量的唯一选择是重新启动应用程序.但是,此限制通常优于使用多个应用程序域的大型性能,内存和代码复杂性开销.如果您希望使用Types,这种限制也是不可避免的.


您可以同时使用新类型.你在技术上并没有"重装"装配.相反,您将与旧组件并排加载新组件.如果程序集经常更改,您最终将耗尽内存并需要重新启动应用程序.
推荐阅读
Chloemw
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有