Tell me, please, how not to keep the dll, after using the following construction:

Assembly a = Assembly.LoadFile(dll); Type t = a.GetTypes().FirstOrDefault(x => x.Name == "MainDllClass"); MethodInfo mi = t.GetMethod("WorkTimer"); mi.Invoke(null, arguments); 

Call the WorkTimer method from the MainDllClass class of the dll file. For some reason, after testing, it continues to be used and does not allow overwriting the dll file

hmm it seems like this:

  AppDomain dom = AppDomain.CreateDomain("some"); AssemblyName assemblyName = new AssemblyName(); assemblyName.CodeBase = pathToAssembly; Assembly a = dom.Load(assemblyName); Type t = a.GetTypes().FirstOrDefault(x => x.Name == "MainDllClass"); MethodInfo mi = t.GetMethod("WorkTimer"); mi.Invoke(null, arguments); AppDomain.Unload(dom); 

I will test, then accomplish your goal.

    1 answer 1

    The fact is that the Assembly.Load() , Assembly.LoadFrom() , Assembly.LoadFile() methods load the assembly into the current application domain on an ongoing basis. This download blocks assembly files. The only way to unload an assembly is to unload the whole application domain.
    There is a trick to avoid blocking assemblies, which is called shadow copying : MSDN. Shadowing builds


    If you don’t need to unload the library, but only need the library to be safely removed / replaced when the application instance is running (for example, updating an ASP.NET application), then you can use the overloaded version of Assembly.Load() which receives the library’s “image” as an array bytes, for example:

    Library:

     namespace TestLib { public class Summator { public int Sum(int x, int y) => x + y; } } 

    Using:

     static void Main(string[] args) { var raw = File.ReadAllBytes(@"Путь\До\Файла\TestLib.dll"); var assembly = Assembly.Load(raw); Type type = assembly.GetTypes().First(x => x.Name == "Summator"); var instance = Activator.CreateInstance(type); MethodInfo mInfo = type.GetMethod("Sum"); var res = (int)mInfo.Invoke(instance, new object[] { 10, 15 }); Console.WriteLine(res); Console.ReadLine(); } 
    • one
      It seems that it is. Thanks for the answer, while I hold it in the clear. Perhaps there is an option to create some kind of crutch, like a temporary application domain to load into it, use and unload the entire domain with AppDomain.Unload, but the English-language stack adheres to the same version as yours. - xSx
    • Andrew, I added the answer with a crutch about which I thought based on your answer, do you think this is the place to be? - xSx
    • @xSx, test - see) - Andrew NOP
    • Strange, but it works :) - xSx
    • @xSx, supplemented the answer - Andrey NOP