Problem mit MEF - ExportFactory<T> in Caliburn.Micro
-
15-10-2019 - |
Frage
Ich verwende MEF in Caliburn.Micro zum Exportieren von Ansichtsmodellklassen.Ich möchte die ExportFactory-Klasse anstelle des Export-Attributs verwenden, da ich versuche, dasselbe Problem wie hier beschrieben zu lösen:Objektzerstörungsproblem mit MEF
Ich versuche, dieses Problem zu lösen, Beispiel:
Einige Ansichtsmodelle - WPF-Fenster:
[Export(typeof(IChatViewModel))]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class ChatViewModel : Screen, IViewModelIdentity,
IChatViewModel, IHandle<Rp>, IHandle<DetailData>
{}
Ich öffne den Chat-Bildschirm mit dem Fenstermanager in einer anderen Ansichtsmodellklasse:
private IWindowManager _windowManager;
var chatScreen = IoC.Get<IChatViewModel>();
_windowManager.Show(chatScreen);
Dann schließe ich den Bildschirm, aber das Objekt dieser Klasse ist noch am Leben.Ich versuche das gleiche Problem wie hier beschrieben:Objektzerstörungsproblem mit MEF
Ich habe ein Ansichtsmodell - es ist ein WPF-Fenster
SZENARIO / LÖSUNG
Ich habe 3 Ansichtsmodelle/Bildschirm:
- LogOnViewModel – Benutzersteuerung
- MessengerViewModel – Benutzersteuerung
- ChatViewModel – WPF-Fenster
Der Code dieser Ansichtsmodelle ist hier:
//#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
{
}
Meine Schale sieht so aus:
//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);
}
}
Ich möchte die Klasse „ExportFactory“ für die Klasse „Erstellungsansichtsmodelle“ verwenden.Ich versuche, die gleiche Logik wie hier zu implementieren: http://mef.codeplex.com/wikipage?title=PartCreator.
Also erstelle ich einen eigenen Controller für die Erstellung von Ansichtsmodellklassen:
Hier ist es:
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;
}
}
Ich importiere die ViewModelsControler-Klasse in diese Klassen:
- ShellViewModel
- MessengerViewModel
Und möchte eine Methode der Klasse ViewModelsControler zur Erstellung der Klasse „Ansichtsmodelle“ verwenden.- Listenpunkt
Ich weiß nicht, was ich falsch mache. Wenn ich versuche, diesen Code zu kompilieren, erhalte ich diese Fehlermeldung:
Es konnten keine Instanzen des Vertrags Spirit.ViewModels.IShellViewModel gefunden werden.Taktrace:bei Spirit.bootStreaper.Mefbootstrapper.getInstance (Typ servicetype, String -Schlüssel) in C: user Jan Dokumente Visual Studio 2010 Projects C# pokec_messger ver.beta pokec__messger spirit_caliburn_micro_v1.0 myf boots.micr_v1.0 myf boots.micr_v1.0 myfbout_micr_v1. : Zeile 59 bei caliburn.micro.ioc.gett in C: user jan documents visual Studio 2010 Projects C# pokec_messenger ver.beta pokec__messger caliburn_micro_completed caliburnmicro src src src src src caliburn.micro.micro.micro.micro.micro. .cs: Zeile 33 bei caliburn.micro.bootstrapper`1.displayrootview () in C: user Jan documents visual Studio 2010 projects c# pokec_messenger ver.beta pokec__messger caliburn caliburn comicro_Micro_Completed caliburnmicro srcicro_completled caliburnmicro srcicro_completed caliburnmicrosger .Micro.SilverlightBootstrapper.cs:line 175 at Caliburn.Micro.Bootstrapper.OnStartup(Object sender, StartupEventArgs e) in C:UsersJanDocumentsVisual Studio 2010ProjectsC#Pokec_Messengerver.beta Pokec__messenger caliburn_micro_completed caliburnmicro src caliburn.micro.Silverlight bootstrapper.cs: Linie 128 bei System.Windows.Application. .Windows.threading.ExceptionWrapper.internalrealcall (Delegate Callback, Objektargs, Int32 numargs) bei Frauinternal.Threading.ExceptionFilterHelper.trycatchwhen (Objektquelle, Delegate -Methode, Objektargs, Int32 numargs, Delegat Catchhandler)
Wenn ich das Exportattribut für die Modellklasse der Erstellungsansicht verwende, funktioniert es gut.
Etwas wie das:
[Export(typeof(ILogOnViewModel))]
public class LogOnViewModel : Screen,ILogOnViewModel
{}
Und 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);
}
}
Wo kann es Probleme geben?In der MEF-Boostraper-Klasse?Ich verwende das klassische MEF-Boostrape:http://devlicio.us/blogs/rob_eisenberg/archive/2010/07/08/caliburn-micro-soup-to-nuts-pt-2-customizing-the-bootstrapper.aspx
Vielen Dank für den Rat, Ihre Zeit und Hilfe.
Lösung
Sie benötigen weiterhin Exporte für die Klassen, die Sie exportieren möchten.Mit ExportFactory können Sie mehrere Instanzen erstellen. Dies funktioniert jedoch nicht, wenn Sie kein Exportattribut für das Objekt haben, von dem Sie Instanzen erstellen möchten.