我的 MEF 导出有任何问题吗?
Is there any problems with my MEF Exports?
我收到一个错误:
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 设置其数据上下文,这又导入了一个 IServiceFactory 实例。 我确定错误是由于 IServiceFactory 和 MEF 引起的。.......我的意思是导出或导入。我猜是因为当我删除 MenuViewModel 中的 ImportingConstructor 和 IServiceFactory 声明时,我的程序运行良好。
我已经使用 MefX 检查了 MEF 上的错误。以下是结果:
这是我的代码:
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>();
}
}
引导程序(客户端):
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;
}
}
引导程序(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();
}
}
项目
如果有人想看一下,这是我的项目:
问题是您的 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));
}
}
对于您的引导程序配置,应用程序在启动时停止抛出异常。 (但它仍然没有显示任何内容)
为了添加该类型,我需要在主应用程序中添加对其他项目的引用。
我收到一个错误:
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 设置其数据上下文,这又导入了一个 IServiceFactory 实例。 我确定错误是由于 IServiceFactory 和 MEF 引起的。.......我的意思是导出或导入。我猜是因为当我删除 MenuViewModel 中的 ImportingConstructor 和 IServiceFactory 声明时,我的程序运行良好。
我已经使用 MefX 检查了 MEF 上的错误。以下是结果:
这是我的代码:
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>();
}
}
引导程序(客户端):
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;
}
}
引导程序(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();
}
}
项目
如果有人想看一下,这是我的项目:
问题是您的 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));
}
}
对于您的引导程序配置,应用程序在启动时停止抛出异常。 (但它仍然没有显示任何内容)
为了添加该类型,我需要在主应用程序中添加对其他项目的引用。