我在wpf中使用了caliburn micro和MEF,我遇到了这个问题。
我创建了shell-view-model:
public interface IShellViewModel
{
void ShowLogOnView();
void ShowMessengerView(PokecAccount account);
}
[Export(typeof(IShellViewModel))]
public class ShellViewModel : Conductor<IScreen>, IShellViewModel
{
public ShellViewModel()
{
ShowLogOnView();
}
public void ShowLogOnView()
{
ActivateItem(IoC.Get<LogOnViewModel>());
}
public void ShowMessengerView(PokecAccount account)
{
//send to constructor of MessangerViewModel paramter typeof PokecAccount(own class)
ActivateItem(IoC.Get<MessengerViewModel>(account));
}
}
从视图模型中我创建并在新视图模型中显示
[Export]
public class LogOnViewModel : Screen, IDataErrorInfo, ILogOnViewModel
{
[Import]
private IShellViewModel _shellViewModel;
[Import]
private IPokecConnection _pokecConn;
private PokecAccount _account;
public void LogOn(string nick, string password)
{
_account = _pokecConn.LogOn(nick, password);
if (_account != null)
{
//create new view-model and show it, problem is send parameter to construtor of MessengerViewModel
_shellViewModel.ShowMessengerView(_account);
}
}
}
问题在这里
//send to constructor of MessangerViewModel paramter typeof PokecAccount(own class)
ActivateItem(IoC.Get<MessengerViewModel>(account));
新视图模型
[Export]
public class MessengerViewModel : Screen, IMessengerViewModel
{
private PokecAccount _account;
public MessengerViewModel(PokecAccount account)
{
_account = account;
}
}
问题出在这里:
//send to constructor of MessangerViewModel paramter typeof PokecAccount(own class)
ActivateItem(IoC.Get<MessengerViewModel>(account));
参数IoC.Get()只能是字符串。
如何解决这个问题?
答案 0 :(得分:2)
我不会在此上下文中使用IoC类,因为这是服务定位器反模式的示例,因此不建议使用。 Rob在他的Caliburn.Micro文档中提到了这一点。您还可以阅读http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx以获得反模式的详细描述。
相反,我会使用抽象工厂模式,并将工厂(抽象)传递到shell视图模型中。这可以有方法来创建新的登录视图模型和信使视图模型。在这个工厂的具体实现中,您可以手动实例化这些视图模型,并传递它们所需的信息。
我还会从登录视图模型中删除对shell视图模型的引用。相反,要么使用shell可以订阅的标准.NET事件,要么查看Caliburn.Micro中实现的事件聚合器(codeplex站点上提供了一个示例),这是一个中介设计模式的实现。这将确保您的视图模型之间的良好解耦。