导入属性始终为null(MEF导入问题)

我尝试使用MEF完成一些事情,但现在,我遇到了一个需要帮助的问题。

说明:我有2个DLL和一个EXE文件。 ClassLibrary1(LoggerImpl.cs,SomeClass.cs)ClassLibrary2(ILogger.cs)WindowsApplicationForms1(WindowsApplicaitonForms1.cs,Program.cs)

我需要任何帮助或方向,为什么这不起作用?

// ClassLibrary1.dll //SomeClass.cs public class SomeClass { [Import("Logging", typeof(ILogger))] public ILogger Log { get; set; } <-- ALWAYS NULL ??? public void Print() { Log.Print(); } } // ClassLibrary1.dll // LoggerImpl.cs namespace ClassLibrary1 { [Export("Logging", typeof (ILogger))] public class LoggerImpl : ILogger { public void Print() { Console.WriteLine("print called"); } } } // ClassLibrary2.dll // ILogger.cs namespace LogNamespace { public interface ILogger { void Print(); } } // WindowsFormsApplication1.exe // WindowsFormsApplication1.cs namespace WindowsFormsApplication1 { [Export("Form1",typeof(Form1))] public partial class Form1 : Form { [Import("Logging", typeof(ILogger))] public ILogger Log { set; get; } private CompositionContainer _container; public Form1() { InitializeComponent(); Compose(); Log.Print(); SomeClass c = new SomeClass(); c.Print(); } private void Compose() { var catalog = new AggregateCatalog(); catalog.Catalogs.Add(new DirectoryCatalog(".")); catalog.Catalogs.Add(new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly())); _container = new CompositionContainer(catalog); try { _container.ComposeParts(this); } catch (CompositionException compositionException) { MessageBox.Show(compositionException.ToString()); } } } } 

如果你自己创建一个新的类实例(new SomeClass()),容器将不会知道它的任何内容,也不会组成它。

对于由MEF组成的部分,它需要由MEF创建,或者显式传递给容器。 你可以手动告诉MEF满足SomeClass对象的导入,就像你告诉它满足表单的导入一样:

 SomeClass c = new SomeClass(); _container.SatisfyImports(c); c.Print(); 

但是,您需要直接访问容器来执行此操作,因此它不能在Form1类之外工作。 通常,更好的方法是导出SomeClass,并在Form1类中为SomeClass创建一个导入:

 [Export] public class SomeClass { [Import("Logging", typeof(ILogger))] public ILogger Log { get; set; } // etc. } public partial class Form1 : Form { [Import("Logging", typeof(ILogger))] public ILogger Log { set; get; } [Import] SomeClass _someClass { get; set; } // etc. } 

您需要一个类似于以下内容的语句,以在合成过程中涉及SomeClass

 // ClassLibrary1.dll //SomeClass.cs using System; using System.ComponentModel.Composition; using System.ComponentModel.Composition.Hosting; using System.Windows.Forms; using LogNamespace; public class SomeClass { [Import("Logging", typeof(ILogger))] public ILogger Log { get; set; } //<-- ALWAYS NULL ??? public SomeClass() { var catalog = new AggregateCatalog(); CompositionContainer _container; // catalog.Catalogs.Add(new DirectoryCatalog(".")); catalog.Catalogs.Add(new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly())); _container = new CompositionContainer(catalog); _container.ComposeParts(this); } public void Print() { Log.Print(); } } // ClassLibrary1.dll // LoggerImpl.cs namespace ClassLibrary1 { [Export("Logging", typeof(ILogger))] public class LoggerImpl : ILogger { public void Print() { Console.WriteLine("print called"); } } } // ClassLibrary2.dll // ILogger.cs namespace LogNamespace { public interface ILogger { void Print(); } } // WindowsFormsApplication1.exe // WindowsFormsApplication1.cs namespace WindowsFormsApplication1 { [Export("Form1", typeof(Form1))] public partial class Form1 : Form { [Import("Logging", typeof(ILogger))] public ILogger Log { set; get; } private CompositionContainer _container; public Form1() { InitializeComponent(); Compose(); Log.Print(); SomeClass c = new SomeClass(); c.Print(); } private void Compose() { var catalog = new AggregateCatalog(); // catalog.Catalogs.Add(new DirectoryCatalog(".")); catalog.Catalogs.Add(new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly())); _container = new CompositionContainer(catalog); try { _container.ComposeParts(this); } catch (CompositionException compositionException) { MessageBox.Show(compositionException.ToString()); } } } }