2014-03-19 128 views
1

我们需要按顺序运行数据库更新。每个数据库更新都将是它自己的DLL,并且需要保留对我们的域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) 

然后让我的主要程序加载&调用每个更新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; 

不幸的是,经过测试此设计和询问版本号,我发现每个更新XXXX.dll正在使用最新的Domain.dll,即使较早的一个存储在它自己的子文件夹中。我假设他们正在通过GAC解决它们的依赖关系,或者默认已经加载到主程序中的依赖项。 (顺便说一句我看到在Visual Studio中,这是不可能给力“的具体版本”一个项目参考和快速谷歌夫表明,这并不简单。)

我的问题:

哪有我强制更新程序集将其对域dll的依赖性解析为其本地文件夹?

或者:

我可以明确地注入动态加载组件的依赖?

编辑:我找到了答案,见下文。

回答

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(); 
    } 
} 
相关问题