Я использую Caliburn.Micto в качестве фреймворка MVVM для моего приложения WPF, а также MEF для инъекций.
UML моего приложения выглядит так: http://i54.tinypic.com/2n1b4mx.png
Мой сценарий таков: я создаю в модели представления-1 (в проекте LogOnViewModel) новую модель представления-2 (в моем проекте - MessengerViewModel) с методом оболочки-представления-модели.
Мне нужно передать объект из модели представления-1 в конструктор модели представления-2.
Я использую MEF в классе инъекций из внешней сборки, которая загружается в класс boostraper.
При создании новых моделей представления я использую абстрактный фабричный шаблон, вот моя реализация:
/// <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 выглядит следующим образом:
/// <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);
}
}
}
Запустите модель представления. Класс Логонвиевмодел:
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;} по-прежнему null.
Какое наиболее подходящее решение в моем случае? Где проблема? Спасибо за помощь.