我们需要按顺序运行数据库更新。每个数据库更新都将是它自己的DLL,并且需要保留对我们的域DLL的特定版本的依赖性(在编写更新时的当前版本)。例如:
Cool.Program.Update0001.dll is dependent on Cool.Program.Domain.dll version 1.0.1
Cool.Program.Update0002.dll is dependent on Cool.Program.Domain.dll version 1.0.3
Cool.Program.Update0003.dll is dependent on Cool.Program.Domain.dll version 1.1.6
我的计划是存储这些DLL&它们在子文件夹中的依赖DLL如下:
%APP%\Cool\Program\Updates\0001\Cool.Program.Update0001.dll
%APP%\Cool\Program\Updates\0001\Cool.Program.Domain.dll (version 1.0.1)
%APP%\Cool\Program\Updates\0002\Cool.Program.Update0002.dll
%APP%\Cool\Program\Updates\0002\Cool.Program.Domain.dll (version 1.0.3)
%APP%\Cool\Program\Updates\0003\Cool.Program.Update0003.dll
%APP%\Cool\Program\Updates\0003\Cool.Program.Domain.dll (version 1.1.6)
然后让我的主程序加载&使用反射动态地按顺序调用每个Update DLL:
var path = System.IO.Path.GetDirectoryName(typeof(this).Assembly.Location) + "\\Updates\\" + versionNumber + "\\Cool.Program.Update" + versionNumber + ".dll";
var assembly = System.Reflection.Assembly.LoadFile(path);
var type = assembly.GetTypes().First(x => x.Name == "Updater");
var method = type.GetMethod("DoYourThing");
var result = method.Invoke(null, dbConnection) as string;
不幸的是,在测试了这个设计并询问版本号之后,我发现每个UpdateXXXX.dll都在使用LATEST Domain.dll,即使较早的版本存储在自己的子文件夹中。我假设他们正在通过GAC解析他们的依赖关系,或者默认为已经加载到主程序中的依赖关系。 (顺便说一句,我在Visual Studio中看到,不可能强迫"特定版本"对于项目参考和快速google-fu建议这不是直截了当。)
我的问题:
如何强制更新程序集解析其对域dll到其本地文件夹的依赖性?
或者:
我可以为动态加载的程序集明确注入依赖项吗?
编辑:我找到了答案,见下文。
答案 0 :(得分:0)
我已经回答了我自己的问题,因为我已经完成了这个问题。
这段代码可以解决问题:
// versionNumber = "0001", "0002" etc
var basePath = Path.GetDirectoryName(typeof(this).Assembly.Location) + "\\Updates\\" + versionNumber + "\\";
var updateAssemblyPath = Path.Combine(basePath, "Cool.Program.Update" + versionNumber + ".dll");
var setup = AppDomain.CurrentDomain.SetupInformation;
setup.ApplicationBase = basePath;
var newDomain = AppDomain.CreateDomain("Updater for " + versionNumber, null, setup);
var obj = (ICanDoSomething)newDomain.CreateInstanceFromAndUnwrap(updateAssemblyPath, "TestDynamicAssemblyLoading.Update"+ versionNumber + ".Class1");
var result = obj.TellMeYourVersionsAndDependencyVersions();
MessageBox.Show(result);
它假定正在使用的类实现了一个已知的接口(例如," ICanDoSomething")并继承自MarshalByRefObject:
public class Class1 : MarshalByRefObject, ICanDoSomething
{
public string TellMeYourVersionsAndDependencyVersions()
{
return
typeof(Class1).Assembly.GetName().Version + "\n\n" +
"My reference to Domain\n=================\n " + SomeModel.TellMeYourVersionsAndDependencyVersions() + "\n\n" +
"My reference to Common\n=================\n " + SomeUtility.TellMeYourVersion();
}
}