我们知道dotnet的dll的依赖dll,要么加入GAC要么就要在exe的目录下才能反射加载,放到path目录下都不行。
不过网上通过这种加载搜索的方式可以实现非exe目录的依赖dll加载。
a. My C# program will load a dll (which is dynamic), for now let's take a.dll (similarly my program will load more dll like b.dll, c.dll, etc....).
b. My program will invoke a method "Onstart" inside a.dll (it's constant for all the dll).
I am able to achieve the above 2 cases by reflection mechanism.
The problem is
a. If my a.dll have any reference say xx.dll or yy.dll, then when I try to Invoke
OnStart method of a.dll from my program. I am getting "could not load dll or one of its dependency". See the code snippet
Assembly assm = Assembly.LoadFrom(@"C:/Balaji/Test/a.dll");foreach (Type tp in assm.GetTypes()){ if (tp.IsClass) { MethodInfo mi = tp.GetMethod("OnStart"); if (mi != null) { object obj = Activator.CreateInstance(tp); mi.Invoke(obj,null); break; } } }
typically i am getting error on the line "object obj = Activator.CreateInstance(tp);" this is because a.dll has reference of xx.dll, but in my program i don't have the reference of xx.dll. Also, I cannot have the reference of xx.dll in my program because a.dll is a external assembly and can have any reference on it's own.
Basically, in the AssemblyResolve event, you need to load the referenced assemblies manually.
private Assembly AssemblyResolveHandler(object sender,ResolveEventArgs e){ try { string[] assemblyDetail = e.Name.Split(','); string assemblyBasePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); Assembly assembly = Assembly.LoadFrom(assemblyBasePath + @"/" + assemblyDetail[0] + ".dll"); return assembly; } catch (Exception ex) { throw new ApplicationException("Failed resolving assembly", ex); }}
Not the best code, but should give you a general idea, I hope.
I do, however, agree that plugin-dlls should be packaged for complete, dependancy-less use. If they are allowed to load assemblies you don't have control over, then who knows what might happen.