Wpf IoC MEF注入问题
我使用Caliburn.Micto作为我的WPF应用程序的MVVM框架,也使用MEF作为注入 我的应用程序的UML如下所示: 我的场景是:我使用shell视图模型方法在view-model-1(项目中为LogOnViewModel)中创建新的view-model-2(项目中为Messenger视图模型) 我需要将对象从view-model-1传递给view-model-2的构造函数 我在boostraper类中加载的外部程序集中的injection类上使用MEF 在创建新视图模型时,我使用抽象工厂模式,以下是我的实现:Wpf IoC MEF注入问题,wpf,inversion-of-control,mef,caliburn.micro,Wpf,Inversion Of Control,Mef,Caliburn.micro,我使用Caliburn.Micto作为我的WPF应用程序的MVVM框架,也使用MEF作为注入 我的应用程序的UML如下所示: 我的场景是:我使用shell视图模型方法在view-model-1(项目中为LogOnViewModel)中创建新的view-model-2(项目中为Messenger视图模型) 我需要将对象从view-model-1传递给view-model-2的构造函数 我在boostraper类中加载的外部程序集中的injection类上使用MEF 在创建新视图模型时,我使用抽象工
/// <summary>
/// Factory interfaces
/// </summary>
public interface IViewModelFactory
{
ILogOnViewModel CreateLogOnViewModel(IShellViewModel shellViewModel);
IMessengerViewModel CreateMessengerViewModel(IShellViewModel shellViewModel, PokecAccount account);
}
/// <summary>
/// Concrent implementation of factory
/// </summary>
[Export(typeof(IViewModelFactory))]
public class DefaulFactoryViewModel:IViewModelFactory
{
#region Implementation of IViewModelFactory
//create start up view-model
public ILogOnViewModel CreateLogOnViewModel(IShellViewModel shellViewModel)
{
return new LogOnViewModel(shellViewModel);
}
//this method create new view model
//it is used in LogOnViewModel
public IMessengerViewModel CreateMessengerViewModel(IShellViewModel shellViewModel, PokecAccount account)
{
return new MessengerViewModel(shellViewModel, account);
}
}
//
///工厂接口
///
公共接口IViewModelFactory
{
ILogOnViewModel CreateLogOnViewModel(IShellViewModel shellViewModel);
IMessengerViewModel CreateMessengerViewModel(IShellViewModel shellViewModel、PokeAccount帐户);
}
///
///工厂的具体实施
///
[导出(类型(IViewModelFactory))]
公共类DefaulFactoryViewModel:IViewModelFactory
{
#IViewModelFactory的区域实现
//创建启动视图模型
公共ILogOnViewModel CreateLogOnViewModel(IShellViewModel shellViewModel)
{
返回新LogOnViewModel(shellViewModel);
}
//此方法用于创建新的视图模型
//它用于LogOnViewModel
公共IMessengerViewModel CreateMessengerViewModel(IShellViewModel shellViewModel、PokeAccount帐户)
{
返回新的Messenger视图模型(shellViewModel,帐户);
}
}
我在shell视图模型中使用这个工厂类。Shell视图模型类如下所示:
/// <summary>
/// Shell model interface
/// </summary>
public interface IShellViewModel
{
//create start up view-model
void ShowLogOnView();
//this method create new view model
//it is used in LogOnViewModel
void ShowMessengerView(PokecAccount account);
}
[Export(typeof(IShellViewModel))]
public class ShellViewModel : Conductor<IScreen>, IShellViewModel
{
//factory interface
private readonly IViewModelFactory _factory;
[ImportingConstructor]
public ShellViewModel(IViewModelFactory factory)
{
//inject factory
_factory = factory;
//show startup view model
ShowLogOnView();
}
public void ShowLogOnView()
{
//create LogOnViewModel class with factory
var model = _factory.CreateLogOnViewModel(this);
ActivateItem(model);
}
/// <summary>
/// Create MessengerViewModel
/// </summary>
/// <param name="account">account in this case is send from LogOnViewModel class </param>
public void ShowMessengerView(PokecAccount account)
{
//create MessengerViewModel class with factory
var model = _factory.CreateMessengerViewModel(this, account);
ActivateItem(model);
}
}
}
//
///外壳模型接口
///
公共界面IShellViewModel
{
//创建启动视图模型
void ShowLogOnView();
//此方法用于创建新的视图模型
//它用于LogOnViewModel
作废ShowMessenger视图(PokeAccount帐户);
}
[导出(类型(IShellViewModel))]
公共类ShellViewModel:导体,IShellViewModel
{
//工厂接口
私有只读IViewModelFactory\u工厂;
[导入构造函数]
公共ShellViewModel(IViewModelFactory工厂)
{
//注射厂
_工厂=工厂;
//显示启动视图模型
ShowLogOnView();
}
公共无效ShowLogOnView()
{
//使用factory创建LogOnViewModel类
var model=_factory.CreateLogOnViewModel(此);
激活体(模型);
}
///
///创建Messenger视图模型
///
///本例中的帐户是从LogOnViewModel类发送的
公开作废ShowMessenger视图(PokeAccount帐户)
{
//使用factory创建Messenger ViewModel类
var model=_factory.CreateMessengerViewModel(这个,帐户);
激活体(模型);
}
}
}
启动视图模型。LogOnViewModel类:
public interface ILogOnViewModel : IScreen, IDataErrorInfo
{
string Nick { get; set; }
string Password { get; set; }
bool CanLogOn { get; set; }
void LogOn(string nick, string password);
}
public class LogOnViewModel : Screen, ILogOnViewModel
{
/// <summary>
/// inject class from external assembly
/// after creation of this class is still null
/// </summary>
[Import]
public IPokecConnection PokecConn { get; set; }
private readonly IShellViewModel _shellViewModel = null;
private PokecAccount _account = null;
public LogOnViewModel(IShellViewModel shellViewModel)
{
_shellViewModel = shellViewModel;
_account = new PokecAccount();
}
//CREATE NEW VIEW MODEL
public void CreateNewView()
{
//create new view-model (MessengerViewModel)
_shellViewModel.ShowMessengerView(_account);
}
}
public interface IMessengerViewModel : IScreen
{
BitmapImage AvatarImage { get; set; }
string AvatarStatus { get; set; }
KeyValuePair<string, Friend> SelectedFriend { get; set; }
}
public class MessengerViewModel : Screen, IMessengerViewModel
{
[Import]
private IPokecService _pokecService;
[Import]
private IPokecConnection _pokecConn;
private IShellViewModel _shellViewModel = null;
private PokecAccount _account = null;
public MessengerViewModel(IShellViewModel shellViewModel, PokecAccount account)
{
_shellViewModel = shellViewModel;
_account = account;
}
}
公共接口ILogOnViewModel:IScreen,IDataErrorInfo
{
字符串Nick{get;set;}
字符串密码{get;set;}
bool CanLogOn{get;set;}
无效登录(字符串尼克、字符串密码);
}
公共类LogOnViewModel:屏幕,ILogOnViewModel
{
///
///从外部程序集注入类
///创建此类后,该类仍然为null
///
[进口]
公共IPokeConnection pokeconn{get;set;}
私有只读IShellViewModel _shellViewModel=null;
私有PokeAccount _account=null;
公共登录视图模型(IShellViewModel shellViewModel)
{
_shellViewModel=shellViewModel;
_账户=新的PokeAccount();
}
//创建新视图模型
public void CreateNewView()
{
//创建新视图模型(Messenger视图模型)
_shellViewModel.ShowMessengerView(_帐户);
}
}
信使视图模型类:
public interface ILogOnViewModel : IScreen, IDataErrorInfo
{
string Nick { get; set; }
string Password { get; set; }
bool CanLogOn { get; set; }
void LogOn(string nick, string password);
}
public class LogOnViewModel : Screen, ILogOnViewModel
{
/// <summary>
/// inject class from external assembly
/// after creation of this class is still null
/// </summary>
[Import]
public IPokecConnection PokecConn { get; set; }
private readonly IShellViewModel _shellViewModel = null;
private PokecAccount _account = null;
public LogOnViewModel(IShellViewModel shellViewModel)
{
_shellViewModel = shellViewModel;
_account = new PokecAccount();
}
//CREATE NEW VIEW MODEL
public void CreateNewView()
{
//create new view-model (MessengerViewModel)
_shellViewModel.ShowMessengerView(_account);
}
}
public interface IMessengerViewModel : IScreen
{
BitmapImage AvatarImage { get; set; }
string AvatarStatus { get; set; }
KeyValuePair<string, Friend> SelectedFriend { get; set; }
}
public class MessengerViewModel : Screen, IMessengerViewModel
{
[Import]
private IPokecService _pokecService;
[Import]
private IPokecConnection _pokecConn;
private IShellViewModel _shellViewModel = null;
private PokecAccount _account = null;
public MessengerViewModel(IShellViewModel shellViewModel, PokecAccount account)
{
_shellViewModel = shellViewModel;
_account = account;
}
}
公共接口IMessengerViewModel:isScreen
{
BitmapImage AvatarImage{get;set;}
字符串AvatarStatus{get;set;}
KeyValuePair SelectedFriend{get;set;}
}
公共类Messenger视图模型:屏幕,IMESsenger视图模型
{
[进口]
私人ipokecs服务(pokecService);;
[进口]
私人IPokecConnection_pokeconn;
私有IShellViewModel _shellViewModel=null;
私有PokeAccount _account=null;
公共信使视图模型(IShellViewModel shellViewModel、PokeAccount帐户)
{
_shellViewModel=shellViewModel;
_账户=账户;
}
}
我对视图模型类的注入有问题。在创建视图模型类时,我使用factory模式,但我也需要从外部组件中注入此类
例如:创建LogonViewModel后,类是IPokeConnection PokeConn{get;set;}仍然为空
在我的情况下,什么是最合适的解决方案?问题出在哪里?谢谢您的帮助。您使用的factory模式除了编写ViewScreenModel类本身之外,不会进行任何编写。如果视图模型不是通过注入创建的,则需要告诉MEF组合视图模型。在返回实例之前,更新factory类以组合实例
public ILogOnViewModel CreateLogOnViewModel
{
var model = new LogOnViewModel();
var container = // set this to your reference of CompositionContainer
container.ComposeParts(model);
return model;
}
…其中,Bootstapper.Container
是您的CompositionContainer
实例
另一方面,为什么要创建另一个帐户,而不是使用您正在使用的factory模式除了构成ViewScreenModel类本身之外,不会进行任何合成。如果视图模型不是通过注入创建的,则需要告诉MEF组合视图模型。在返回实例之前,更新factory类以组合实例
public ILogOnViewModel CreateLogOnViewModel
{
var model = new LogOnViewModel();
var container = // set this to your reference of CompositionContainer
container.ComposeParts(model);
return model;
}
…其中,Bootstapper.Container
是您的CompositionContainer
实例
另一方面,你为什么用另一个账户,而不是使用