[英]MEF Property Always Returning Null
原始源代码
我的 BusinessObjects.dll 文件中有一个简单的业务 object:
namespace BusinessObjects
{
public class MyClass
{
public MyClass()
{
DateTime = DateTime.Now;
}
public DateTime DateTime { get; set; }
}
}
在我的 SharedUI.dll 中,我有这个“上下文提供者”class,我用它来保存对当前选择的 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 有这个 class:
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();
}
}
}
我做错了什么,因为我无法让它工作?
当 MEF 需要获取 class 的属性上的导出时,它将创建 class 的实例并调用属性获取器。 因此,MEF 正在创建 AppContext 的新实例,与 static AppContext.Context 实例不同。 MEF 创建的实例没有设置 SelectedMyClass 属性,这就是您的导入最终成为 null 的原因。
问题是:
[Import] public MyClass MyClass { get; set; }
没有为 MyClass 定义 [Export]。 MEF 将根据它“知道”的东西组成这个应用程序,因为它不知道“MyClass”......
我注意到了这个:
[Export] public MyClass SelectedMyClass { get; private set; }
这意味着您正试图欺骗 MEF 不时更新它的某个部分? 解决方案是创建一个包含“运行时”对象的自定义目录,您可以在其中随时更新 MyClass 的导出值。 当前的实现永远不会解决 MyClass ...
[编辑:] 你也可以装饰一个成员,但你必须在那里添加 class 类型。 所以这将起作用:
[Export(typeof(MyClass)] public MyClass SelectedMyClass { get; private set; }
您将Export
属性放在错误的位置。
你应该把它放在MyClass
的定义上,如下所示:
namespace BusinessObjects
{
[Export]
public class MyClass
{
public MyClass()
{
DateTime = DateTime.Now;
}
public DateTime DateTime { get; set; }
}
}
然后在需要此 class 实例的任何地方使用 [Import] 属性。
备注:您不能使用 MEF 移动 class 的特定实例(不是这样)。
MEF 用于创建请求类型的实例并将它们注入指定的位置。
要了解有关 MEF 的更多信息,请查看CodePlex上的项目页面。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.