1

我使用 Caliburn.Micto 作为我的 WPF 应用程序的 MVVM 框架以及用于注入的 MEF。

我的应用程序的 UML 如下所示:http: //i54.tinypic.com/2n1b4mx.png

我的场景是:我使用 shell-view-model 方法在 view-model-1(项目中是 LogOnViewModel)中创建新的 view-model-2(在我的项目中是 MessengerViewModel)。

我需要将对象从 view-model-1 传递给 view-model-2 的构造函数。

我在 boostraper 类中加载的外部程序集的注入类上使用 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);
  }

 }

我在我的 shell-view-model 中使用这个工厂类。Shell-view-model 类如下所示:

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

}

启动视图模型。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);
 }

}

MessengerViewModel 类:

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

我在注入视图模型类时遇到问题。在创建视图模型类时,我使用工厂模式,但我也需要从外部程序集中注入此类。

例如:创建 LogOnVieModel 类后是 IPokecConnection PokecConn{ get; set;} 仍然为空。

在我的情况下,最合适的解决方案是什么?问题出在哪里?感谢您的帮助。

4

1 回答 1

1

您正在使用的工厂模式除了构成 ViewScreenModel 类本身之外不进行任何组合。如果不是通过注入创建的,您需要告诉 MEF 组合您的视图模型。在返回之前更新您的工厂类以组合实例;

public ILogOnViewModel CreateLogOnViewModel
{
    var model = new LogOnViewModel();
    var container = // set this to your reference of CompositionContainer
    container.ComposeParts(model);

    return model;
}

...您的.Bootstapper.Container实例在哪里?CompositionContainer

另一方面,您为什么要创建另一个帐户,而不是使用当前帐户

于 2010-12-19T19:30:04.880 回答