原始资源代码
我的BusinessObjects.dll文件中有一个简单的业务对象:
namespace BusinessObjects
{
public class MyClass
{
public MyClass()
{
DateTime = DateTime.Now;
}
public DateTime DateTime { get; set; }
}
}
在我的SharedUI.dll中,我有了这个“上下文提供程序”类,我用来对当前选择的MyClass进行引用 - 记住这是一个简单的例子:)...
namespace SharedUI
{
public class AppContext
{
[Export]
public MyClass SelectedMyClass { get; private set; }
public void SetupContext(MyClass myClass)
{
SelectedMyClass = myClass;
}
public static AppContext Context
{
get
{
if (context == null)
{
context = new AppContext();
}
return context;
}
}
private static AppContext context;
}
}
我的MefTest.exe有这个类:
namespace MefTest
{
public class Program
{
[Import]
public MyClass MyClass { get; set; }
private void Compose()
{
var ventSystem = new MyClass();
AppContext.Context.SetupContext(ventSystem);
var executingAssembly = new AssemblyCatalog(Assembly.GetExecutingAssembly());
var contextAssembly = new AssemblyCatalog(Assembly.LoadFile(string.Format(@"{0}\SharedUI.dll", Environment.CurrentDirectory)));
var catalog = new AggregateCatalog(executingAssembly, contextAssembly);
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
}
private void Run()
{
Compose();
// MyClass is always null in the next line?
Console.WriteLine(MyClass.DateTime.ToString());
Console.ReadKey();
}
private static void Main(string[] args)
{
var p = new Program();
p.Run();
}
}
}
我是MEF新秀所以请耐心等待我:)
更新的源代码以及Daniel Plaisted的建议
MyClass来源是一样的......
SharedUI.dll现在看起来像这样:
namespace SharedUI
{
[Export]
public class AppContext
{
[Export(typeof(MyClass))]
public MyClass SelectedMyClass { get; private set; }
public void SetupContext(MyClass myClass)
{
SelectedMyClass = myClass;
}
}
}
MefTest.exe现在看起来像这样:
namespace MefTest
{
public class Program
{
[Import]
public MyClass MyClass { get; set; }
[Import]
public AppContext AppContext { get; set; }
private void Compose()
{
var executingAssembly = new AssemblyCatalog(Assembly.GetExecutingAssembly());
var contextAssembly = new AssemblyCatalog(Assembly.LoadFile(string.Format(@"{0}\SharedUI.dll", Environment.CurrentDirectory)));
var catalog = new AggregateCatalog(executingAssembly, contextAssembly);
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
var myClass = new MyClass();
AppContext.SetupContext(myClass);
}
private void Run()
{
Compose();
// AppContext.SelectedMyClass is NOT null in the next line... which is good I guess :)
Console.WriteLine(AppContext.SelectedMyClass.DateTime.ToString());
// MyClass is always null in the next line?
Console.WriteLine(MyClass.DateTime.ToString());
Console.ReadKey();
}
private static void Main(string[] args)
{
var p = new Program();
p.Run();
}
}
}
我做错了什么因为我无法正常工作?
答案 0 :(得分:2)
当MEF需要获取类的属性上的Export时,它将创建该类的实例并调用属性getter。因此,MEF正在创建AppContext的新实例,与静态AppContext.Context实例不同。实例MEF创建的实例没有设置SelectedMyClass属性,这就是导入最终为空的原因。
答案 1 :(得分:1)
问题是:
[Import] public MyClass MyClass { get; set; }
没有为MyClass定义[导出]。 MEF将基于它“知道”的东西组成这个应用程序,因为它不知道“MyClass”......
我注意到了这个:
[Export] public MyClass SelectedMyClass { get; private set; }
这意味着您正试图欺骗MEF不时更新其中一个部分?解决方案是创建一个包含“运行时”对象的自定义目录,您可以随时更新MyClass的导出值。当前的实现永远不会解析MyClass ...
[编辑:] 您也可以装饰成员,但是您必须在那里添加类类型。所以这将有效:
[导出(typeof(MyClass)] public MyClass SelectedMyClass {get; private set;}
答案 2 :(得分:0)
您将Export
属性放在错误的位置。
您应该将其置于MyClass
的定义中,如此:
namespace BusinessObjects
{
[Export]
public class MyClass
{
public MyClass()
{
DateTime = DateTime.Now;
}
public DateTime DateTime { get; set; }
}
}
然后在任何您想要此类实例的地方使用[Import]属性。
备注:您无法使用MEF移动类的特定实例(不是这样)。
MEF用于创建所请求类型的实例,并将其注入指定的位置。
要了解有关MEF的更多信息,请查看项目页面CodePlex。