我正在将CalculatorDependency.dll加载到AppDomain,它是Calculator.dll的Add类(来自Calculator.Interface.dll的IAdd实现)的依赖项。
问题是我不想在执行程序集位置或GAC中放置实现者DLL(Calculator.dll)和它的依赖dll(CalculatorDependency.dll)。我想分别从给定位置动态加载它。所以我正在加载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();
}
错误:
TestConsole.exe中发生了未处理的“System.IO.FileNotFoundException”类型异常
附加信息:无法加载文件或程序集“CalculatorDependency,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null”或其依赖项之一。该系统找不到指定的文件。
加载程序集的控制台输出:
有人可以帮我解决这里有什么问题吗?即使加载了CalculatorDependency.dll,为什么它还在寻找要再次加载的文件?
最后我找到了解决问题的方法。
这对我有用。完美和我在寻找! :)
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();
}
如何在内存流中加载文件然后使用它。 using(FileStream file = new FileStream(@“c:\ temp \ TestAccountScrubbing.dll”,FileMode.Open,FileAccess.Read)){byte [] bytes = new byte [file.Length]; file.Read(bytes,0,(int)file.Length); ms.Write(bytes,0,(int)file.Length); } ms.Seek(0,SeekOrigin.Begin); Assembly assembly = 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" });
}