导入属性总是空(MEF进口问题) [英] Import property always null (MEF import issue)

查看:119
本文介绍了导入属性总是空(MEF进口问题)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试了一段时间把事情用MEF完成,但现在,我遇到一个问题,我需要帮助。



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



我需要任何帮助或指导为什么不起作用?

  // ClassLibrary1.dll 
/ /SomeClass.cs
公共类SomeClass的
{
[导入(记录的typeof(ILogger))]
公共ILogger日志{搞定;组; }< - 总是为空?

公共无效打印()
{
Log.Print();
}

}

// ClassLibrary1.dll
// LoggerImpl.cs
命名空间ClassLibrary1的
{
〔导出(记录的typeof(ILogger))]
公共类LoggerImpl:ILogger
{
公共无效打印()
{
Console.WriteLine( 打印名为);
}
}
}

// ClassLibrary2.dll
// ILogger.cs
命名空间LogNamespace
{
公共接口ILogger
{
无效打印();
}
}

// WindowsFormsApplication1.exe
// WindowsFormsApplication1.cs
命名空间WindowsFormsApplication1
{
[导出( Form1的的typeof(Form1中))]
公共部分Form1类:表格
{

[导入(记录的typeof(ILogger))]
公共ILogger日志{集;得到; }

私人CompositionContainer中_container;

公共Form1中()
{
的InitializeComponent();
撰写();
Log.Print();

SomeClass的C =新SomeClass的();
c.Print();
}

私人无效撰写()
{
变种目录=新AggregateCatalog();

catalog.Catalogs.Add(新DirectoryCatalog()。);
catalog.Catalogs.Add(新AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly()));
_container =新CompositionContainer中(目录);


{
_container.ComposeParts(本);
}
赶上(CompositionException compositionException)
{
MessageBox.Show(compositionException.ToString());
}
}
}
}


解决方案

如果你创建一个类自己(新SomeClass的())的新实例,容器不会知道这件事并不会构成它。



有关的一部分由MEF组成,它需要由MEF创建,或者显式地传递到容器。您可以手动告诉MEF以满足相同的方式SomeClass的对象的进口,你告诉它来满足形式进口:

  SomeClass的Ç =新SomeClass的(); 
_container.SatisfyImports(三);
c.Print();



不过,您需要将容器直达做到这一点,所以它不工作,以及以外的Form1类的。一般情况下,一个更好的方式做这将是出口SomeClass的,并建立在Form1类的导入为SomeClass的:

  [出口] 
公共类SomeClass的
{
[导入(记录的typeof(ILogger))]
公共ILogger日志{搞定;组; }

//等
}

公共部分Form1类:表格
{
[导入(记录的typeof( ILogger))]
公共ILogger日志{设置;得到; }

[导入]
SomeClass的_someClass {搞定;组; }

//等
}


I try for some time to get things done using MEF but now, I run into a problem i need help.

Description: I have 2 DLL and one EXE file. ClassLibrary1 (LoggerImpl.cs, SomeClass.cs) ClassLibrary2 (ILogger.cs) WindowsApplicationForms1 (WindowsApplicaitonForms1.cs, Program.cs)

I need any help or direction why this doesn't work ?

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

解决方案

If you create a new instance of a class yourself (new SomeClass()), the container won't know anything about it and won't compose it.

For a part to be composed by MEF, it needs to be created by MEF, or passed explicitly to the container. You can manually tell MEF to satisfy the SomeClass object's imports in the same way you told it to satisfy the form's imports:

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

However, you need direct access to the container to do this, so it doesn't work as well outside of your Form1 class. In general, a better way to do it would be to export SomeClass, and create an import in your Form1 class for 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.
}

这篇关于导入属性总是空(MEF进口问题)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆