简体   繁体   中英

Import from another assembly throws exception when using MEF

I have a WPF project that expects imports from other assemblies.

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


    }
}

When I export FileViewModel class I get error:

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

I don't understand how this is possible. Most information I found is about assembly versions not matching, but I have a very basic solution and every project has the same version.

I tried using Lazy<IMenuBarItem> Item , but that imports null .

Also I use MefInjector , so I can do imports from classes other than 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);
}

And 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;
        }

Any suggestions, what else I can try to fix this?

did you tell CM about the assembly in SelectAssemblies property override, just merely referencing the assembly in the application doesn't tell CM about it. 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);

    }

So, I guess I fixed it. To be honest I don't know what was wrong. I just removed my project and created a new one. I did everything exactly the same way and now it works. Maybe it was the issue with not matching assemblies, but I don't really know how this would be possible taking into account that I cleaned my folder many times...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM