2012-06-05 74 views
0

我想在ClassLibrary中使用MEF,而不是在應用程序項目中使用(既不是ConsoleApplication也不是WebApplication ...)。在類庫中使用MEF

當我嘗試這樣做(如MSDN:http://msdn.microsoft.com/en-us/library/dd460648.aspx

class Program 
{ 
    private CompositionContainer _container; 

    [Import(typeof(IPlugin))] 
    public IPlugin Plugins; 


    private Program() 
    { 
     //An aggregate catalog that combines multiple catalogs 
     var catalog = new AggregateCatalog(); 
     //Adds all the parts found in the same assembly as the Program class 
     catalog.Catalogs.Add(new AssemblyCatalog(typeof(Program).Assembly)); 
     catalog.Catalogs.Add(new DirectoryCatalog(@".\Extensions")); 


     //Create the CompositionContainer with the parts in the catalog 
     _container = new CompositionContainer(catalog); 

     //Fill the imports of this object 
     try 
     { 
      this._container.ComposeParts(this); 
     } 
     catch (CompositionException compositionException) 
     { 
      Console.WriteLine(compositionException.ToString()); 
     } 
    } 


    static void Main(string[] args) 
    { 
     Program p = new Program(); //Composition is performed in the constructor 
    } 
} 

物業:

[Import(typeof(IPlugin))] 
    public IPlugin Plugins; 

工作正常。

編輯:

不過,我想移動進口財產&總目錄下建立一個ClassLibrary,而不是在我的ConsoleApplication。

像下面這樣的東西。

在ClassLibrary [Manager.dll]:

public class Manager 
{ 
    private CompositionContainer _container; 

    [Import(typeof(IPlugin))] 
    public IPlugin Plugins; 


    public Manager() 
    { 
     //An aggregate catalog that combines multiple catalogs 
     var catalog = new AggregateCatalog(); 
     //Adds all the parts found in the same assembly as the Program class 
     catalog.Catalogs.Add(new AssemblyCatalog(typeof(Manager).Assembly)); 
     catalog.Catalogs.Add(new DirectoryCatalog(@".\Extensions")); 


     //Create the CompositionContainer with the parts in the catalog 
     _container = new CompositionContainer(catalog); 

     //Fill the imports of this object 
     try 
     { 
      this._container.ComposeParts(this); 
     } 
     catch (CompositionException compositionException) 
     { 
      Console.WriteLine(compositionException.ToString()); 
     } 
    } 
} 

而在ConsoleApplication:

class Manager 
{ 
    static void Main(string[] args) 
    { 
     Manager m = new Manager(); //Composition is performed in the constructor 
    } 
} 

但是,當我做到這一點變化,我不能夠得到 「插件」 財產在我的ClassLibrary中總是「空」。

任何人都有解決方案來做到這一點?

+0

簡單地把所有的插件放到類庫中,然後在你的程序中添加一個引用和命名空間聲明有什麼問題嗎?我的印象是,MEF管道本身(包括進口)需要成爲主要應用,才能正常運行。 –

+0

請參閱「[堆棧溢出不需要你的SEO技巧](http://meta.stackexchange.com/a/130208/76337)」。 –

+0

@RobertHarvey:我不想把我所有的插件放在同一個類庫中,也不能。我同意你關於你的感受......我認爲導入需要在它的主要應用程序中正常工作,但我認爲這不是一個好的想法,因爲它可能是複製代碼的來源。 – Sam

回答

2

這可能只是您的目錄的問題。如果你將你的財產轉移到一個類庫中,這意味着一個單獨的程序集。目前,只有主辦「計劃」的大會在您的目錄中,以及「擴展」中的任何內容。那麼,你確定你的新類庫在擴展文件夾中嗎?

另外,您正在撰寫this,這意味着您正在撰寫「Program」的實例。如果您將屬性移動到不同庫中的其他類中,則需要編寫任何類的實例。

事情是這樣的:

class Program 
    { 
    private CompositionContainer _container;  

    private Program() 
    { 
     var helper = new MyOtherHelperClass(); 
     var catalog = helper.CreateCatalog(); 

     //Create the CompositionContainer with the parts in the catalog 
     _container = new CompositionContainer(catalog); 

     //Fill the imports of some object 
     try 
     { 
      var thingIWantToCompose = new OtherClassWithAnImport(); 
      this._container.ComposeParts(thingIWantToCompose); 
     } 
     catch (CompositionException compositionException) 
     { 
      Console.WriteLine(compositionException.ToString()); 
     } 
    } 


    static void Main(string[] args) 
    { 
     Program p = new Program(); //Composition is performed in the constructor 
    } 
} 

如果不工作,然後嘗試尋找在視覺MEFX您的零件。這裏有一個簡短的指南來設置它:Getting Started with Visual MEFX

+0

感謝您的回覆@Jim – Sam