0

这可能看起来像重复,但事实并非如此,它实际上是一个不同的问题!

场景是这样的:我有一个 Web 应用程序,它遍历所有动态加载到系统中的 dll,以从中访问一个方法并获取数据。这些 dll 由网站的用户添加。

伪代码将是这样的:

pulic void GetNews(){
    foreach(var i in ListOfDllPaths){
        Assembly dll = Assembly.Load( File.ReadAllBytes(i));
        SomeInterface if = CreateInstance(dll); //This methods does all the validation and such
        if.DoMethod();
    }
}

现在的问题是,在每次调用 GetNews() 时,都会重新加载相同的 dll,多次加载相同的 dll。我可以使用 Assembly.LoadFrom 或 LoadFile 来避免这个问题,但是我会锁定我不想要的文件,因为我希望能够删除它。

另一种选择是使用新的应用程序域来加载它们,调用方法并卸载它们,但是我还必须在该域中加载接口 dll,而我真的不知道它在网络应用程序中的路径. 更不用说将数据从一个应用程序域移动到另一个应用程序域是一件痛苦的事情,而且很难完成。

第三种选择是使用卷影副本,但随后我将无法删除相同结果的卷影副本。

选项?基本上我需要的是,加载 dll,使用它,卸载它,继续。

4

1 回答 1

3

如果您需要真正卸载它,您别无选择,只能使用单独的应用程序域(例如,请参阅如何从主 AppDomain 卸载程序集?

如果您只需要加载每个程序集一次,但不关心卸载旧程序集,您需要管理跟踪自己加载了哪些程序集。任何简单的方法都是在加载每个文件之前对其进行哈希处理。就像是:

Dictonary<string,bool> loadedAssemblies = new Dictonary<string,bool>();

using(SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider())
{
    var hash = Convert.ToBase64String(sha1.ComputeHash(byteArray));
    if(loadedAssemblies.ContainsKey(hash)) continue;
    loadedAssemblies[hash] = true;
    Assembly dll = Assembly.Load( File.ReadAllBytes(i));
    SomeInterface if = CreateInstance(dll); //This methods does all the validation and such
    if.DoMethod();
}

如果您想对项目进行版本控制,另一种方法是向您的界面添加一些元数据。

于 2013-05-30T01:27:00.263 回答