2010-06-29 104 views
3

我正在使用MEF作爲項目導入插件,因爲插件是用WPF編寫的,它們都有一個視圖和一個視圖模型。插件知道視圖模型,但主外殼UI將構造視圖並使用約定通過配置類型模式綁定視圖模型。Type.GetType在使用MEF時返回null

我已經使用一些代碼從建立你自己的MVVM框架樣本做自動視圖發現:

[ImportMany(typeof(IPlugin))] 
    public IEnumerable<IPlugin> Plugins { get; set; } 

    var viewTypeName = this.Plugins.First().ViewModel.GetType().AssemblyQualifiedName.Replace("Model", string.Empty); 
    var viewType = Type.GetType(viewTypeName,true); 

此刻的代碼只是獲取第一個插件,並從取出Model該名稱,返回視圖名稱並獲取視圖類型,以便我可以構造它。那麼什麼viewType將是一個例子是:

PluginTest.TestView, PluginTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null 

然而,當我打電話Type.GetType(viewType)我回來空,如果我添加了true拋出一個例外,我得到異常:

Could not load file or assembly 'PluginTest, Version=1.0.0.0, Culture=neutral, 
PublicKeyToken=null' or one of its dependencies. 
The system cannot find the file specified. 

即使它已經使用MEF加載。

如果我做的:

var types = Assembly.GetAssembly(this.Plugins.First().ViewModel.GetType()).GetTypes(); 

我回來在插件的程序集中的所有類型的列表,到目前爲止還只是PluginTest.TestViewPluginTest.TestViewModel

誰能幫我這一個?

編輯:對不起,之前沒有提到,插件是在不同的程序集到我的主殼程序。

回答

4

這可能是最容易做的是這樣的:

var modelType = this.Plugins.First().ViewModel.GetType(); 
var viewTypeName = modelType.FullName.Replace("Model", string.Empty); 
var viewType = modelType.Assembly.GetType(viewTypeName); 

我不知道爲什麼Type.GetType工作不適合你 - 大會決議是一個棘手的野獸 - 但如果你知道組裝類型應該在無論如何定義,我一定會通過Assembly.GetType來代替。

+0

它似乎仍然返回null hmmm .. – 2010-06-29 05:58:40

+0

@Nathan:那麼當您嘗試上述代碼時,「viewTypeName」是什麼? – 2010-06-29 06:14:02

+0

ahh沒有抱歉,它的工作原理:)你有沒有modelType.FullName那裏我發誓它是modelType.Name這就是爲什麼我的代碼沒有工作。謝謝。 – 2010-06-29 06:16:51

0

這個問題早已有了答案,但以防萬一有人絆倒在此,這裏是我的解決方案。

正如其他答案已經注意到的,問題是,雖然程序集已經通過MEF加載,但一旦使用GetType()後,程序會再次加載。不幸的是,我無法控制代碼GetType(),所以Jon Skeet的解決方案對我來說不起作用。

就我而言,問題可以通過將插件程序集的位置添加到應用程序的probing path來解決。

另一種解決方案(這是我最終做的)是實現AssemblyResolve事件,並手動加載程序集。這個解決方案非常靈活,與探測路徑解決方案相反,如果您事先不知道插件的安裝目錄,它也可以工作。另外:如果你的插件有任何相關的程序集,你必須使用這兩個解決方案之一,否則你在第一次使用這些依賴時會得到一個FileNotFound異常。