我正在将 CalculatorDependency.dll 加载到 AppDomain ,这是添加类的依赖( IAdd 的实施来自 Calculator.dll 的 Calculator.Interface.dll 。
问题是我不想把实施者dll( Calculator.dll )和它的依赖dll( CalculatorDependency.dll )放在执行装配位置或在GAC中执行。我想分别从给定位置动态加载它。所以我首先加载Interface实现者dll和它对AppDomain的依赖来创建一个实例。
这是我的代码!!
static void Main(string[] args)
{
// Loading dependency dll into memory
var dependency = string.Concat(Directory.GetCurrentDirectory(), @"\Implementations\CalculatorDependency.dll");
var dependencyBytes = File.ReadAllBytes(dependency);
// Loading implementer dll into memory
var implementor = string.Concat(Directory.GetCurrentDirectory(), @"\Implementations\Calculator.dll");
var implementorBytes = File.ReadAllBytes(implementor);
// Adding dependency dll to AppDomain (CalculatorDependency.dll)
AppDomain.CurrentDomain.Load(dependencyBytes);
// Adding implementor dll to AppDomain (Calculator.dll)
AppDomain.CurrentDomain.Load(implementorBytes);
// Checking loaded assemblies and both above assemblies are exist in output
var loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies().ToList();
foreach (var a in loadedAssemblies)
{
Console.WriteLine(a.GetName().Name);
}
// Calling function to get an instance of IAdd as Calculator.Add class from Calculator.dll
var obj = GetObject<IAdd>();
// Object was resolved successfully but was failed at this line as SumNew is a dependent function on CalculatorDependency.dll
Console.WriteLine(obj.SumNew(2, 2));
}
public static T GetObject<T>()
{
var t = typeof(T);
var objects = (
from assembly in AppDomain.CurrentDomain.GetAssemblies()
from type in assembly.GetExportedTypes()
where typeof(T).IsAssignableFrom(type) && !type.FullName.Equals(t.FullName)
select (T)Activator.CreateInstance(type)
).ToArray();
return objects.FirstOrDefault();
}
错误:
未处理的类型&#39; System.IO.FileNotFoundException&#39;发生在TestConsole.exe
中其他信息:无法加载文件或程序集&#39; CalculatorDependency,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null&#39;或其中一个依赖项。系统找不到指定的文件。
已加载程序集的控制台输出:
有人可以帮我解决这里有什么问题吗?即使加载 CalculatorDependency.dll ,为什么它还在寻找要再次加载的文件?
答案 0 :(得分:1)
最后我找到了解决问题的方法。
这对我有用。完美和我在寻找! :)
static void Main(string[] args)
{
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
var implementor = string.Concat(Directory.GetCurrentDirectory(), @"\Implementations\Calculator.dll");
var implementorBytes = File.ReadAllBytes(implementor);
AppDomain.CurrentDomain.Load(implementorBytes);
Console.WriteLine(GetObject<IAdd>().SumNew(2, 2));
Console.WriteLine(GetObject<IAdd>().SumNew(2, 5));
}
static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
var dependencyResolverBaseDirectory = string.Concat(Directory.GetCurrentDirectory(), @"\Implementations");
return Directory.GetFiles(dependencyResolverBaseDirectory, "*.dll")
.Select(Assembly.LoadFile)
.FirstOrDefault(assembly => string.Compare(args.Name, assembly.FullName, StringComparison.CurrentCultureIgnoreCase) == 0);
}
public static T GetObject<T>()
{
var t = typeof(T);
var objects = (
from assembly in AppDomain.CurrentDomain.GetAssemblies()
from type in assembly.GetExportedTypes()
where typeof(T).IsAssignableFrom(type) && (string.Compare(type.FullName, t.FullName, StringComparison.CurrentCultureIgnoreCase) != 0)
select (T)Activator.CreateInstance(type)
).ToList();
return objects.FirstOrDefault();
}
答案 1 :(得分:0)
如何在“内存流”中加载文件然后使用它。 使用(FileStream文件=新FileStream(@“ c:\ temp \ TestAccountScrubbing.dll”,FileMode.Open,FileAccess.Read)) { byte [] bytes =新的byte [file.Length]; file.Read(bytes,0,(int)file.Length); ms.Write(bytes,0,(int)file.Length); } ms.Seek(0,SeekOrigin.Begin); 程序集程序集= Assembly.Load(ms.ToArray());
Type type = assembly.GetType("TestAccountScrubbing.AccountScubbing");
object obj = Activator.CreateInstance(type);
var returnValue =type.InvokeMember("Main",
BindingFlags.Default | BindingFlags.InvokeMethod,
null,
obj,
new object[] { "Hello World" });
}