I use MEF in Caliburn.Micro for export view models classes. I would like use ExportFactory class rather than Export attribute because I try solve same problem as is described here: Object destruction problem with MEF
I try solve this problem, example:
Some view model - WPF window:
[Export(typeof(IChatViewModel))]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class ChatViewModel : Screen, IViewModelIdentity,
IChatViewModel, IHandle<Rp>, IHandle<DetailData>
{}
I open chat screen with window manager in some other view model class:
private IWindowManager _windowManager;
var chatScreen = IoC.Get<IChatViewModel>();
_windowManager.Show(chatScreen);
Then I close screen, but object of this class is still alive. I try same problem as is described here: Object destruction problem with MEF
I have view model - it is WPF window
SCENARIO / SOLUTION
I have 3 view models/screen:
- LogOnViewModel - user control
- MessengerViewModel - user control
- ChatViewModel - WPF Window
Code of these view models is here:
//#1 screen - user control
public class LogOnViewModel : Screen, ILogOnViewModel
{
private IShellViewModel _shell;
[ImportingConstructor]
public LogOnViewModel(IShellViewModel shell)
{
_shell = shell;
}
//....
//Active #2 screen Messenger screen
_shell.ShowMessenger(_account);
//....
}
//#2 screen - user control
public class MessengerViewModel : Screen,IMessengerViewModel
{
private IViewModelsControler _viewModelControler;
private IWindowManager _windowManager;
[ImportingConstructor]
public MessengerViewModel(IViewModelsControler viewModelControler, IWindowManager windowManager)
{
_windowManager = windowManager;
_viewModelControler = viewModelControler;
}
//...
//Open #3 sceen - WPF window
var vindow = _viewModelControler.CreateChatViewModel();
_windowManager.Show(window);
//...
}
//#3 screen - WPF window
[PartCreationPolicy(CreationPolicy.NonShared)]
public class ChatViewModel : Screen, IChatViewModel
{
}
My shell look like this:
//SHELL is WPF window
[Export(typeof(IShellViewModel))]
public class ShellViewModel : Conductor<IScreen>.Collection.OneActive, IShellViewModel
{
[Import]
public IViewModelsControler ViewModelControler{ get; set;}
protected override void OnInitialize()
{
ShowLogOn();
base.OnInitialize();
}
public void ShowLogOn()
{
//var vm = IoC.Get<ILogOnViewModel>();
var vm = ViewModelControler.CreateLogOnViewModel();
ActivateItem(vm);
}
public void ShowMessenger(Account account)
{
ActiveItem.Deactivate(true);
//var vm = IoC.Get<IMessengerViewModel>();
var vm = ViewModelControler.CreateMessengerViewModel();
vm.Account = account;
ActivateItem(vm);
}
}
I would like use ExportFactory class for creation view models class. I try implement same logic as here: http://mef.codeplex.com/wikipage?title=PartCreator.
So I create own controler for creation view models classes:
Here ist it:
public interface IViewModelsControler
{
ILogOnViewModel CreateLogOnViewModel();
IMessengerViewModel CreateMessengerViewModel();
IChatViewModel CreatChatViewModel();
}
[Export(typeof(IViewModelsControler))]
public class ViewModelsControler:IViewModelsControler
{
[Import]
public ExportFactory<ILogOnViewModel> LogOnViewFactory { get; set; }
public ILogOnViewModel CreateLogOnViewModel()
{
return LogOnViewFactory.CreateExport().Value;
}
[Import]
public ExportFactory<IMessengerViewModel> MessengerViewFactory { get; set; }
public IMessengerViewModel CreateMessengerViewModel()
{
return MessengerViewFactory.CreateExport().Value;
}
[Import]
public ExportFactory<IChatViewModel> ChatViewFactory { get; set; }
public IChatViewModel CreatChatViewModel()
{
return ChatViewFactory.CreateExport().Value;
}
}
I import ViewModelsControler class in these classes:
- ShellViewModel
- MessengerViewModel
And would like method of class ViewModelsControler on creation view models class. - List item
I don’t know what I do bad, if I try compile this code a I get this error:
Could not locate any instances of contract Spirit.ViewModels.IShellViewModel. Staktrace: at Spirit.BootStraper.MefBootStrapper.GetInstance(Type serviceType, String key) in C:\Users\Jan\Documents\Visual Studio 2010\Projects\C#\Pokec_Messenger\ver.beta\Pokec__Messenger\Spirit_Caliburn_Micro_v1.0\BootStraper\MefBootStrapper.cs:line 59 at Caliburn.Micro.IoC.GetT in C:\Users\Jan\Documents\Visual Studio 2010\Projects\C#\Pokec_Messenger\ver.beta\Pokec__Messenger\Caliburn_Micro_Completed\CaliburnMicro\src\Caliburn.Micro.Silverlight\IoC.cs:line 33 at Caliburn.Micro.Bootstrapper`1.DisplayRootView() in C:\Users\Jan\Documents\Visual Studio 2010\Projects\C#\Pokec_Messenger\ver.beta\Pokec__Messenger\Caliburn_Micro_Completed\CaliburnMicro\src\Caliburn.Micro.Silverlight\Bootstrapper.cs:line 175 at Caliburn.Micro.Bootstrapper.OnStartup(Object sender, StartupEventArgs e) in C:\Users\Jan\Documents\Visual Studio 2010\Projects\C#\Pokec_Messenger\ver.beta\Pokec__Messenger\Caliburn_Micro_Completed\CaliburnMicro\src\Caliburn.Micro.Silverlight\Bootstrapper.cs:line 128 at System.Windows.Application.OnStartup(StartupEventArgs e) at System.Windows.Application.<.ctor>b__1(Object unused) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
If I use Export attribute on creation view model class, it works good.
Something like this:
[Export(typeof(ILogOnViewModel))]
public class LogOnViewModel : Screen,ILogOnViewModel
{}
And shell:
[Export(typeof(IShellViewModel))]
public class ShellViewModel : Conductor<IScreen>.Collection.OneActive, IShellViewModel
{
protected override void OnInitialize()
{
ShowLogOn();
base.OnInitialize();
}
public void ShowLogOn()
{
var vm = IoC.Get<ILogOnViewModel>();
//var vm = _viewModelControler.CreateLogOnViewModel();
ActivateItem(vm);
}
public void ShowMessenger(Account account)
{
ActiveItem.Deactivate(true);
var vm = IoC.Get<IMessengerViewModel>();
//var vm = _viewModelControler.CreateMessengerViewModel();
vm.Account = account;
ActivateItem(vm);
}
}
Where can be problem? In MEF boostraper class? I use clasic MEF boostrape: http://devlicio.us/blogs/rob_eisenberg/archive/2010/07/08/caliburn-micro-soup-to-nuts-pt-2-customizing-the-bootstrapper.aspx
Thank for advice, your time and help.