简体   繁体   English

在C#MVC中使用MEF,程序集正在加载一些DLL,如何卸载它们?

[英]Using MEF in C# MVC, Assembly Loading some DLLs, how do I unload them?

Sorry in advance I'm not sure if I've phrased the question correctly, here's my situation... Using .NET 4.6 with MEF. 预先抱歉,我不确定我是否正确表达了这个问题,这是我的情况...在MEF中使用.NET 4.6。

I have a core website that, at run time, checks a modules folder for DLLs and pulls them into a Composition Container / MEF thing, which lets me use the views/controllers of the 3rd party project, in my core. 我有一个核心网站,该网站在运行时检查DLL的模块文件夹,并将其拉入Composition Container / MEF组件中,这使我可以在核心中使用第三方项目的视图/控制器。

To allow strong typing, I followed this guide which suggests making a shadow copy of the DLLs in a PreApplicationStartMethod. 为了进行强类型输入,我遵循了该指南该指南建议在PreApplicationStartMethod中制作DLL的卷影副本。

All working so far, really great. 到目前为止一切正常,真的很棒。

The problem comes when I stop debugging or when the server recompiles. 当我停止调试或服务器重新编译时,就会出现问题。 The DLLs are not being released properly, so I get access denied errors 2nd time around. DLL没有被正确释放,因此第二次出现访问拒绝错误。 The error happens when I try to copy DLLs into the shadow copy folder. 当我尝试将DLL复制到卷影复制文件夹时,会发生错误。

The process cannot access the file '....dll' because it is being used by another process.

I guess it's the BuildManager.AddReferencedAssembly(assemblyDll) which is locking the file in... but is there a reliable way to unload the assembly either on crash or on start up? 我猜想是BuildManager.AddReferencedAssembly(assemblyDll)将文件锁定在...但是有可靠的方法可以在崩溃或启动时卸载程序集吗?

static PreApplicationInit()
    {
        PluginFolder = new DirectoryInfo(HostingEnvironment.MapPath("~/Modules"));
        ShadowCopyFolder = new DirectoryInfo(HostingEnvironment.MapPath("~/Modules/temp"));
    }
public static void Initialize()
    {
        Directory.CreateDirectory(ShadowCopyFolder.FullName);

        //clear out plugins)
        foreach (var f in ShadowCopyFolder.GetFiles("*.dll", SearchOption.AllDirectories))
        {
            f.Delete(); // -- Breaks here
        }

        //shadow copy files
        foreach (var plug in PluginFolder.GetFiles("*.dll", SearchOption.AllDirectories))
        {
            var di = Directory.CreateDirectory(Path.Combine(ShadowCopyFolder.FullName, plug.Directory.Name));
            File.Copy(plug.FullName, Path.Combine(di.FullName, plug.Name), true); // -- Or if Delete is Try Caught, Breaks here
        }

        foreach (var a in
            ShadowCopyFolder
            .GetFiles("*.dll", SearchOption.AllDirectories)
            .Select(x => AssemblyName.GetAssemblyName(x.FullName))
            .Select(x => Assembly.Load(x.FullName)))
        {
            BuildManager.AddReferencedAssembly(a);
        }

    }

There can be many possible reasons but the main reason for this i think is, when you recompile some of the dll from your previous compile are still in process and it wont let you have access until the entire process is finished (which in a term it will have a lock). 可能有很多可能的原因,但是我认为主要原因是,当您从以前的编译中重新编译某些dll时,它仍在处理中,直到整个过程完成后,它才允许您访问(这总之是将有一个锁)。 if you want to recompile try changing the folder. 如果要重新编译,请尝试更改文件夹。 it should work. 它应该工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM