开发者

IoC-MEF injection problem

I use Caliburn.Micto as MVVM framework for my WPF application and also MEF for injection.

UML of my application look like this: http://i54.tinypic.com/2n1b4mx.png

My scenario is: I create in view-model-1 (in project is LogOnViewModel) new view-model-2 (in my project is MessengerViewModel) with shell-view-model method.

I need pass object from view-model-1 to constructor of view-model-2.

I use MEF on injection class from external assembly which is loaded in boostraper class.

On creation of new view-models I use abstract factory pattern, here is my implementation:

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

 }

I use this factory class in my shell-view-model. Shell-view-model class look like this:

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

}

Start up view-model. LogOnViewModel class:

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 class:

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

I have problem with injection into view-model class. On creation of view-model classes I use factory pattern, but I need inject in this class also from external assembly.

For example: After creation of LogOnVieModel class is IPokecConnection PokecConn{ get; set;} still开发者_运维知识库 null.

What is the most suitable solution in my case? Where is it problem ? Thank for help.


The factory pattern you are using doesn't do any composition outside of composing the ViewScreenModel class itself. You need to tell MEF to compose your view models, if they are not being created through injection. Update your factory class to compose the instance before returning it;

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

    return model;
}

...where Bootstapper.Container is your instance of CompositionContainer.

On another note, why have you made another account, instead of using your current one

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜