使用MEF时从另一个程序集导入会引发异常

时间:2016-11-01 17:30:11

标签: c# wpf import mef caliburn.micro

我有一个WPF项目,期望从其他程序集导入。

namespace DrawMe.Core.ViewModels
{
    public class MenuBarViewModel : Conductor<IMenuBarItem>
    {
        [Import(typeof(IMenuBarItem))]
        public IMenuBarItem Item { get; set; }

        public MenuBarViewModel()
        {
            MefInjector.Inject(this);     
        }
    }
}


namespace DrawMe.MenuBarItems.ViewModels
{
    [Export(typeof(IMenuBarItem))]
    public class FileViewModel : Screen, IMenuBarItem
    {
        public string Name { get; set; }
        public List<IMenuBarOption> Options { get; set; }


    }
}

当我导出FileViewModel课程时,我收到错误:

The export 'DrawMe.MenuBarItems.ViewModels.FileViewModel (ContractName="DrawMe.Api.Models.MenuBar.IMenuBarItem")' is not assignable to type 'DrawMe.Api.Models.MenuBar.IMenuBarItem'.

我不明白这是怎么回事。我发现的大多数信息都与组件版本不匹配,但我有一个非常基本的解决方案,每个项目都有相同的版本。

我尝试使用Lazy<IMenuBarItem> Item,但导入null

我也使用MefInjector,因此我可以从MainViewModel以外的类进行导入。

public static readonly string ExtensionFolderPath = Path.GetFullPath(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\Extensions");
private static readonly DirectoryCatalog DirectoryCatalog = new DirectoryCatalog(ExtensionFolderPath);
private static readonly CompositionContainer Container = new CompositionContainer(DirectoryCatalog);

public static void Inject<T>(T obj) where T : class 
{
    Container.ComposeParts(obj);
}

和Bootstrapper

protected override IEnumerable<Assembly> SelectAssemblies()
        {
            var assemblies = Directory.GetFiles(MefInjector.ExtensionFolderPath, "*.dll", SearchOption.AllDirectories).Select(Assembly.LoadFrom).ToList();
            assemblies.Add(Assembly.GetExecutingAssembly());
            return assemblies;
        }

有什么建议,我还可以尝试解决这个问题吗?

2 个答案:

答案 0 :(得分:0)

您是否告诉CM有关SelectAssemblies属性覆盖中的程序集,仅仅引用应用程序中的程序集并不告诉CM它。 http://caliburnmicro.com/documentation/bootstrapper

protected override IEnumerable<Assembly> SelectAssemblies()
    {
        var assemblies = base.SelectAssemblies();

        var directory = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory);
        var files = directory.GetFiles("*.dll", SearchOption.TopDirectoryOnly);
        var modules = files.Where(f => f.Name.Contains("SomeAssemblyNamespacePrefixorProjectName"))
                                  .Select(f => Assembly.LoadFile(f.FullName));

        return assemblies.Concat(modules);

    }

答案 1 :(得分:0)

所以,我想我修好了。说实话,我不知道出了什么问题。我刚删除了我的项目并创建了一个新项目。我做了一切完全相同的方式,现在它的工作原理。也许这是不匹配组件的问题,但考虑到我多次清理我的文件夹,我真的不知道这是怎么可能的......