2014-04-15 24 views
3

我是MEF的新手,想知道什麼是正確的方式把它放在一起用於我的設置,因爲我讀過的所有基本教程都沒有涵蓋序列化的基礎。MEF和序列號

我有一個由模塊組成的系統(全部來源於通用基類型B)。在運行期間,模塊被創建(=從類型列表中選出併發送到Activator)並且被動態地移除(通過用戶輸入)。這些模塊的實例存儲在列表結構(List<B>)中,並且模塊類型都是可序列化的。因此,要堅持/檢索模塊的狀態,這個列表只需簡單地進行序列化/反序列化。

我現在想要做的是將不同類型的模塊打包到不同的程序集中,以實現更好的可擴展性。然而,「未知類型」的反序列化(從而意味着MEF發現的程序集類型)似乎不起作用。所以我想到了一個像這樣工作的解決方案。假設一個API接口,它包裝模塊創造:

進口
interface IModulePlugin { 
    string FullyQualifiedName {get; } 
    Type ModuleType {get; } 

    B GetInstance();   // create new instance (Activator) 
    B GetInstance(Stream s); // recreate instance by deserialization   

    Stream Serialize(); 
} 

現在,經過...

[ImportMany(typeof(IModulePlugin))] 
List<IModulePlugin> plugins; 

...在例如列表中的元素註冊(unambigious)名稱和模塊類型一個字典,以便在序列化期間可以將該名稱與模塊的數據一起存儲。

反序列化的過程,然後會變成這樣的事情:

  • 讀名稱,並嘗試獲取相應的插件
  • 呼叫GetInstance()針對與數據的插件反序列化
  • ...

這是這樣做嗎?似乎在我眼中有點複雜,我不確定這實際上會起作用。這個想法是將序列化所需的知識傳遞給模塊/插件。然而,如果插件必須相互依賴(比如'核心'插件和'核心擴展')或版本控制,它會變得更加複雜。

(順便說一句:我使用C#5 .NET 4.5和BinaryFormatter的)

感謝您的答覆!

回答

0

我會評論,但我沒有足夠的聲望。看到你的問題來自去年...我想知道你找到了什麼解決方案,你選擇了什麼解決方案。

編輯:也許這會幫助別人。

我做的是:獲取我想從MEF組件中保存的類型列表,並通過System.Runtime.Serialization.DataContractSerializer保存它們。 它具有可以在構造函數中設置的Knowntypes屬性。

MEF_ComponenentList.Select(item => item.GetType()); 

public static void SerializeSomething<T>(T objToSave, string fileToSaveTo, IEnumerable<Type> KnownTypes = null) 
    { 
     var ser = new System.Runtime.Serialization.DataContractSerializer(typeof(T)); 
     var settings = new XmlWriterSettings { Indent = true }; 
     System.IO.File.Delete(fileToSaveTo); 
     if (KnownTypes != null) 
     { 
      var sum = ser.KnownTypes.Concat(KnownTypes); 
      ser = new System.Runtime.Serialization.DataContractSerializer(typeof(T), sum); 
     } 
     using (var writer = XmlWriter.Create(fileToSaveTo, settings)) 
     { 
      ser.WriteObject(writer, objToSave); 
     } 
    } 

你必須小心你的屬性,你公開等...或者你必須使用IgnoreDataMember。