Alternative to AppDomain.AppendPrivatePath?

I read a lot of things mainly through google (not here, on SO) and did not find something that answered my question, so I ask for it here.

What I want to add to "something" (to AppDomain , I think) so that my code can allow AT RUNTIME, like Assembly.CreateInstance specific DLL that is outside my application compilation folder.

It really seems to me that AppDomain is the class to use, and AppendPrivatePath sounds like a method to use, but now it is "deprecated" ... msdn suggests using PrivateBinPath, but as I understand it, I need to create a new AppDomain with my tests too It seems to me that Assembly.CreateInstance not looking for links in my new AppDomain

Some code, for example:

 AppDomainSetup domaininfo = new AppDomainSetup(); domaininfo.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory; domaininfo.PrivateBinPath = "D:\\.....\\bin\\Debug\\"; Evidence adevidence = AppDomain.CurrentDomain.Evidence; AppDomain newDomain = AppDomain.CreateDomain("FrameworkDomain", adevidence, domaininfo); 

works, but then when I try CreateInstance I got a TargetInvocation exception

I also tried:

 Thread.GetDomain().SetupInformation.PrivateBinPath = "D:\\.....\\bin\\Debug\\"; 

which sounds โ€œspecialโ€ but good for me, but it doesnโ€™t work ...

It really seems to me that I should pass the path D:\\.....\\bin\\Debug\\ to the current AppDomain, but it is no longer possible, since AppendPrivatePath deprecated ...

Any help?

+4
source share
4 answers

You can enable additional DLLs yourself if the assembly fails, so you know that it cannot find the type.

 AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += MyResolve; AppDomain.CurrentDomain.AssemblyResolve += MyResolve; private Assembly MyResolve(Object sender, ResolveEventArgs e) { Console.Error.WriteLine("Resolving assembly {0}", e.Name); // Load the assembly from your private path, and return the result } 
+3
source

I could completely track what you are actually trying to create, but assuming you want to create a plugin infrastructure where you want to organize plugins in subfolders, for example:

 \plugins\foo\foo.dll \plugins\foo\dependency_that_foo_needs.dll \plugins\bar\bar.dll \plugins\bar\dependency_that_bar_needs.dll 

The problem that you are facing is that foo.dll does not load its dependency, because the framework does not look in this subdirectory to load the assembly.

Using the latest Managed Extensibility Framework (MEF 2 Preview), you can easily create these things. I suppose you can even do this with an earlier version, however earlier versions forced you to use special attributes in your plugins so that the latest version no longer depends.

So, suppose this is your contract with the plugin:

 public interface IPlugin { string Run(); } 

To load and run all plugins in \ plugins \ foo \, \ plugins \ bar \, (...), just use this code:

 class Program { static void Main(string[] args) { var registration = new RegistrationBuilder(); registration.ForTypesDerivedFrom<IPlugin>().Export().Export<IPlugin>(); var directoryInfo = new DirectoryInfo("./plugins"); var directoryCatalogs = directoryInfo .GetDirectories("*", SearchOption.AllDirectories) .Select(dir => new DirectoryCatalog(dir.FullName, registration)); var aggregateCatalog = new AggregateCatalog(directoryCatalogs); var container = new CompositionContainer(aggregateCatalog); container .GetExportedValues<IPlugin>() .ForEach(plugin => Console.WriteLine(plugin.Run())); Console.ReadLine(); } } 

As I said, I could be completely out of the track, but there is a chance that someone is looking for an alternative, this is useful :-)

+2
source

How about using

 Assembly.LoadFrom("..path) 
0
source

You can add an EventHandler to the Appdomains AssemblyResolve event, and then load your assemblies from a special private path.

0
source

Source: https://habr.com/ru/post/1392897/


All Articles