我的MEF出口有问题吗?

时间:2016-05-08 16:17:44

标签: c# wpf xaml prism mef

我收到错误:

An exception has occurred while trying to add a view to region 'MenubarRegion'. 
    - The most likely causing exception was was: 
      'Microsoft.Practices.ServiceLocation.ActivationException: Activation error occured 
      while trying to get instance of type MenuView, key "" ---> 

我的MenuView使用MEF通过MenuViewModel设置其datacontext,这会导入一个IServiceFactory实例。 我确信由于IServiceFactory和MEF而发生错误。 .......我的意思是出口或进口。我想这是因为当我在MenuViewModel中删除ImportingConstructor和IServiceFactory声明时,我的程序运行良好。

我已经使用MefX检查了MEF上的错误。结果如下:

enter image description here

enter image description here

enter image description here

这是我的代码:

MenuView.xaml.cs

[Export]
[PartCreationPolicy(CreationPolicy.NonShared)]
public partial class MenuView : UserControlViewBase
{
    [ImportingConstructor]
    public MenuView(MenuViewModel viewModel)
    {
        InitializeComponent();
        this.DataContext = viewModel;
    }
}

MenuViewModel.cs

[Export]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class MenuViewModel : ViewModelBase
{

    IServiceFactory _ServiceFactory;

    [ImportingConstructor]
    public MenuViewModel(IServiceFactory serviceFactory)
    {
        _ServiceFactory = serviceFactory;
    }

    protected override void OnViewLoaded()
    {
        _MenuItems = new ObservableCollection<MenuItem>();

        WithClient<IMenuItemService>(_ServiceFactory.CreateClient<IMenuItemService>(), menuItemClient =>
        {
            MenuItem[] menuItems = menuItemClient.GetAllParentMenuItemsWithChildren();
            if (menuItems != null)
            {
                foreach (MenuItem menuItem in menuItems)
                {
                    _MenuItems.Add(menuItem);
                }

                _SelectedMenuItem = _MenuItems[2];
            }

        });
    }

    private ObservableCollection<MenuItem> _MenuItems;

    public ObservableCollection<MenuItem> MenuItems
    {
        get
        {
            return _MenuItems;
        }
        set
        {
            if (_MenuItems != value)
            {
                _MenuItems = value;
                OnPropertyChanged(() => MenuItems, false);
            }
        }
    }

    private MenuItem _SelectedMenuItem;

    public MenuItem SelectedMenuItem
    {
        get
        {
            return _SelectedMenuItem;
        }
        set
        {
            if (_SelectedMenuItem != value)
            {
                _SelectedMenuItem = value;
                OnPropertyChanged(() => SelectedMenuItem);
            }
        }
    }

}

IServiceFactory.cs

public interface IServiceFactory
{
    T CreateClient<T>() where T : IServiceContract;
}

ServiceFactory.cs

[Export(typeof(IServiceFactory))]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class ServiceFactory : IServiceFactory
{
    public T CreateClient<T>() where T : IServiceContract
    {
        return ObjectBase.Container.GetExportedValue<T>();
    }
}

Bootstrapper(客户端):

public static class MEFLoader
{
    public static CompositionContainer Init()
    {
        return Init(null);
    }

    public static CompositionContainer Init(ICollection<ComposablePartCatalog> catalogParts)
    {
        AggregateCatalog catalog = new AggregateCatalog();

        catalog.Catalogs.Add(new AssemblyCatalog(typeof(MenuItemClient).Assembly));
        catalog.Catalogs.Add(new AssemblyCatalog(typeof(MEFLoader).Assembly));

        if (catalogParts != null)
            foreach (var part in catalogParts)
                catalog.Catalogs.Add(part);

        CompositionContainer container = new CompositionContainer(catalog);

        return container;
    }
}

Bootstrapper(业务方面)

public static class MEFLoader
{
    public static CompositionContainer Init()
    {
        AggregateCatalog catalog = new AggregateCatalog();

        catalog.Catalogs.Add(new AssemblyCatalog(typeof(MunimPlusEngine).Assembly));
        catalog.Catalogs.Add(new AssemblyCatalog(typeof(MenuItemManager).Assembly));
        catalog.Catalogs.Add(new AssemblyCatalog(typeof(MenuItemRepository).Assembly));
        catalog.Catalogs.Add(new AssemblyCatalog(typeof(MEFLoader).Assembly));

        CompositionContainer container = new CompositionContainer(catalog);

        return container;

    }
}

Bootstrapper(WPF主要应用程序)

public class BootStrapper : MefBootstrapper
{
    protected override DependencyObject CreateShell()
    {
        return Container.GetExportedValue<Shell>();
    }

    protected override void InitializeShell()
    {
        base.InitializeShell();
        App.Current.MainWindow = (Window)Shell;
        App.Current.MainWindow.Show();
    }

    protected override void ConfigureAggregateCatalog()
    {
        base.ConfigureAggregateCatalog();
        AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(BootStrapper).Assembly));
        AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(RegionNames).Assembly));
        AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(ModuleMenu.Module).Assembly));
    }
}

App.xaml.cs

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);

        ObjectBase.Container = MEFLoader.Init(new List<ComposablePartCatalog>()
                                                    {
                                                        new AssemblyCatalog(Assembly.GetExecutingAssembly())
                                                    });

        BootStrapper bootstrapper = new BootStrapper();
        bootstrapper.Run();

    }
}

项目

如果有人想看一下,这是我的项目:

Download Project

1 个答案:

答案 0 :(得分:2)

问题是您的ServiceFactory实施没有添加到MEF目录中。当你添加:

    public class BootStrapper : MefBootstrapper
{
    protected override DependencyObject CreateShell()
    {
        return Container.GetExportedValue<Shell>();
    }

    protected override void InitializeShell()
    {
        base.InitializeShell();
        App.Current.MainWindow = (Window)Shell;
        App.Current.MainWindow.Show();
    }

    protected override void ConfigureAggregateCatalog()
    {
        base.ConfigureAggregateCatalog();
        AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(BootStrapper).Assembly));
        AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(RegionNames).Assembly));
        AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(ModuleMenu.Module).Assembly));
        //Added catalog 
        //--> 
            AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(ServiceFactory).Assembly));
    }
}

到你的bootstrapper配置,应用程序停止在启动时抛出异常。 (但它仍然没有显示任何内容)

为了添加该类型,我需要在主应用程序中添加对其他项目的引用。