我尝试使用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());
}
}
}
}
答案 0 :(得分:28)
如果你自己创建一个新的类实例(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.
}
答案 1 :(得分:1)
您需要一个类似于以下内容的声明,以便在合成过程中使用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());
}
}
}
}