导入属性始终为空(MEF 导入问题)

发布于 2024-08-13 01:43:11 字数 1995 浏览 1 评论 0原文

我尝试了一段时间使用 MEF 来完成工作,但现在遇到了一个问题,我需要帮助。

描述: 我有 2 个 DLL 和 1 个 EXE 文件。 ClassLibrary1(LoggerImpl.cs、SomeClass.cs) 类库2 (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());
            }
        }
    }
}

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

逐鹿 2024-08-20 01:43:11

如果您自己创建类的新实例(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.
}

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.
}
意中人 2024-08-20 01:43:11

您需要类似于以下的语句才能将 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());
            }
        }
    }
}

You need a statement like similar to the following to involve the SomeClass in the composition process

// 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());
            }
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文