MEF财产总是空无一人

时间:2011-05-04 12:01:04

标签: c# import export properties mef

原始资源代码

我的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();
        }
    }
}

我做错了什么因为我无法正常工作?

3 个答案:

答案 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