我認識到,MEF僅適用於metro風格的應用程序。沒有容器了,那麼如何獲得特定的導出值,如ILogger logger = container.GetExportedValues<ILogger>();
? 是否有涵蓋MEF城域版本的任何教程?如何在metro風格應用程序中獲取導出值(MEF)
感謝您的幫助, ENY
我認識到,MEF僅適用於metro風格的應用程序。沒有容器了,那麼如何獲得特定的導出值,如ILogger logger = container.GetExportedValues<ILogger>();
? 是否有涵蓋MEF城域版本的任何教程?如何在metro風格應用程序中獲取導出值(MEF)
感謝您的幫助, ENY
正如我已經在評論中寫道,我真的不喜歡這種方法,但它是最好的我有什麼了這一刻:
public class CompositionContainer
{
private readonly CompositionService _service;
public CompositionContainer(CompositionService service)
{
_service = service;
}
public T GetExportedValue<T>()
{
var factoryProvider = new FactoryProvider<T>();
_service.SatisfyImportsOnce(factoryProvider);
return factoryProvider.Factory.CreateExport().Value;
}
private class FactoryProvider<T>
{
[Import]
public ExportFactory<T> Factory;
}
}
和簡單的使用情況可能是這樣之一:
class Program
{
static void Main()
{
var catalog = new ApplicationCatalog();
var container = new CompositionContainer(catalog.CreateCompositionService());
for (int i = 0; i < 5; i++)
{
var dude = container.GetExportedValue<IDude>();
Console.WriteLine(dude.Say());
}
}
public interface IDude
{
string Say();
}
[Export(typeof(IDude))]
public class Eminem : IDude
{
private static int _instanceNo;
private readonly string _phrase;
public Eminem()
{
_instanceNo++;
_phrase = string.Join(" ", Enumerable.Range(0, _instanceNo)
.Select(_ => "yo!"));
}
public string Say()
{
return _phrase;
}
}
}
我不在乎在這個時刻的表現,但我想我會添加工廠供應商或工廠的緩存後
這不是一個壞方法!只是一個可憐的,我們必須編寫這樣的代碼自己:(謝謝老兄。 – Enyra 2012-03-14 19:51:43
我猜你已經發現了System.CompononentModel.Composition
和System.CompononentModel.Composition.Hosting
命名空間。
讓我給你一個簡單的例子(看看你是否錯過了什麼)。所有的
首先你需要一個組件注入:
public interface IMefTest
{
string Message {get;}
}
[Export(typeof(IMefTest))]
public class MefTest: IMefTest
{
public string Message {get { return "Hello World"; }}
}
接下來你需要建立CompositionService
(這類似於一個容器,但不完全)。我們希望將它設置在某個可以共同討論的地方,因爲這將是您調用的滿足導入的地方(更多關於此代碼片段的內容)。在這個
static System.ComponentModel.Composition.ICompositionService _compositionService = null;
public static System.ComponentModel.Composition.ICompositionService CompositionService
{
get
{
if (_compositionService == null)
((App)App.Current).loadCompositionService();
return _compositionService;
}
}
private void loadCompositionService()
{
// Create a catalog where MEF will search for exported parts to plugin
var catalog = new System.ComponentModel.Composition.Hosting.AssemblyCatalog(GetType().GetTypeInfo().Assembly);
_compositionService = catalog.CreateCompositionService();
}
只是一點點信息:
我在示例項目陷入這種在App.xaml.cs。我們已經建立了一個彙編目錄,這意味着MEF只會詢問本大會尋找出口的類型。還有其他類型的目錄,我相信你應該能夠將2個或更多的目錄結合在一起。好的,在我的頁面中(順便說一下,我將它構建到MSDN入門文檔中的C#HelloWorld示例中)。
要獲得目錄中某個零件的實例,您只需將屬性添加到要獲取的類並添加一個imports屬性(也有方法可以在構造函數中指定參數,但我試圖保持簡單)
[Import]
public IMefTest Tester { get; set; }
在這個例子中,你需要調用的組合服務的SatisfyImportsOnce方法這個類。我這樣做是在構造函數中,我這樣做是這樣的:
if(App.CompositionService != null)
App.CompositionService.SatisfyImportsOnce(this);
(的檢查,以確保該服務存在矯枉過正是我的一部分..它應該存在)。 完成該步驟後,您實際上可以在班級中使用Tester.Message
屬性。 MEF中有更多的選擇。我希望這可以幫助你(如果它是你的標誌我作爲答案,因爲我從帳單客戶寶貴的時間爲你做這個)
此外,我知道你想簡單地調用一個容器,並讓它給你支持某種類型的實例。可以用其他形式的MEF來做到這一點,所以我認爲應該可以用WinRT來完成,但我現在確實不確定)。
你好DevTheo,我已經知道了,不幸的是,它不是我正在搜索的。允許容器獲取特定的導出值,但不能滿足任何導入:container.GetExportedValue
對不起,我沒有爲你釘......我不能完全找到你想要的東西(就像我說的需要回到客戶的工作
我不指望你爲我釘;)我已經有一個想法,我怎麼能做到這一點,但我還沒有足夠的時間呢^^但我不認爲這可以做到沒有一些自定義代碼。 – Enyra 2012-03-05 18:59:15
你找到一個解決方案?我已經結束了ExportFactory和SatisfyImportsOnce,但我不滿意,我只需要GetExportedValues – 2012-03-13 22:43:29
我正在與開發MEF的地鐵風格應用程序之一的人聯繫。他告訴我,SatisfyImportsOnce目前是撰寫項目的唯一方法。他問我,我記住哪些具體情況不受SatisfyImportOnce支持: http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/6aff302d-867a-4921-86ae-b8088c47560f 我發現暫時MEF的一個微小的替代: http://metroioc.codeplex.com/ 希望它也能幫助你。 – Enyra 2012-03-14 17:56:23
我不想使用其他框架,因爲我想在項目之間共享一些代碼。並且儘快在源項目中使用MEF,我想繼續使用它。我的需求不是太大,所以我更願意添加缺少的功能。我將添加我當前的解決方案作爲答案。 – 2012-03-14 19:36:49