2014-10-10 61 views
1

我正在嘗試使用MEF實現工廠模式。工廠模式與託管擴展框架(MEF)

這裏是我的解決方案

核心項目

IClass 
ObjectFactory static Class(This is where the problem is) 

項目A

[Export(typeof(IClass))] 
[ExportMetadata("Type", "TypeA")] 
public classA : IClass 
{} 

項目B

[Export(typeof(IClass))] 
[ExportMetadata("Type", "TypeB")] 
public classB : IClass 
{} 

我面臨的問題,當我試圖創建對象dynami凱莉

這裏是工廠類:

public static class ObjectFactory 
{ 
    private static readonly CompositionContainer _container; 

    [ImportMany] 
    public static IEnumerable<Lazy<IClass, IMetaData>> objectTypes; 
    static ObjectFactory() 
    { 
     AggregateCatalog catalog = new AggregateCatalog(); 

     catalog.Catalogs.Add(new DirectoryCatalog(Environment.CurrentDirectory)); 
     _container = new CompositionContainer(catalog); 

     try 
     { 
      objectTypes = _container.GetExports<IClass, IMetaData>(); 
     } 
     catch (CompositionException compositionException) 
     { 
      Console.WriteLine(compositionException.ToString()); 
      Console.ReadLine(); 
     } 
    } 

    public static IClass CreateObject(ObectType objectType) 
    { 
     IClass outProvider; 

     Type typeToLoad = objectTypes.Where(x => x.Metadata.Type == objectType.ToString()).FirstOrDefault().GetType(); 
     outProvider = (IClass)Activator.CreateInstance(typeToLoad); 

     return outProvider; 
    } 
} 

回答

1

話,我建議這個重構。

private static readonly CompositionContainer _container; 

static ObjectFactory() 
{  
    var directoryCatalog = new DirectoryCatalog(Environment.CurrentDirectory) 
    _container = new CompositionContainer(directoryCatalog);   
} 

public static IClass CreateObject(ObectType objectType) 
{  
    var objectTypes objectTypes = new List<Lazy<IClass, IMetaData>>(); 
    try 
    { 
     objectTypes.AddRange(_container.GetExports<IClass, IMetaData>()); 
    } 
    catch (CompositionException compositionException) 
    { 
     Console.WriteLine(compositionException.ToString()); 
     Console.ReadLine(); 
    } 

    return objectTypes.FirstOrDefault(x => x.Metadata.Type == objectType.ToString()); 
} 

你看MEF將解決新的實例(非共享那些是)每次構成類型的時間,或者你打電話GetExports(這個函數的所有其他重載)。或者,您可以導出IClass工廠,那麼您將擁有一批那裏的提供者。

P.S.你的例子中的objectTypes成員上的[ImportMany]是多餘的,因爲你沒有編寫這種類型(我不相信你可以從靜態開始),你只需從GetExports的輸出程序設置它即可

+0

感謝您的更新EdZ。有用。我還沒有意識到我的objectType在類級別是靜態的,並且每次都給出相同的對象。 來到你的構造函數參數上的Q,我改變了classA和ClassB def並刪除了構造函數的參數。現在它可以工作,每次它給我新的實例。 – user3397876 2014-10-13 17:57:38

0

如果你想提供在每次調用的CreateObject一個新的「非共享」例如,我可以解決這個問題

public static IClass CreateObject(ObectType objectType) 
    { 
     return objectTypes.Where(x => x.Metadata.Type == objectType.ToString()).FirstOrDefault().Value; 
    } 
+0

儘管它起作用現在,我看到每次它返回相同的實例。我在ClassA和ClassB之上添加了 [PartCreationPolicy(System.ComponentModel.Composition.CreationPolicy.NonShared)] 。任何建議? – user3397876 2014-10-10 23:17:17