2014-03-19 85 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(); 
    } 
} 
相關問題