1

我在 wpf 中使用 caliburn micro 和 MEF,我遇到了这个问题。

我创建外壳视图模型:

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() 只能是字符串。

如何解决这个问题?

4

1 回答 1

2

我不会在这种情况下使用 IoC 类,因为这是服务定位器反模式的一个示例,不推荐使用。Rob 在他的 Caliburn.Micro 文档中提到了这一点。您还可以阅读http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx以获得对反模式的很好描述。

相反,我会使用抽象工厂模式,并将工厂(的抽象)传递到您的 shell 视图模型中。这可以具有创建新登录视图模型和信使视图模型的方法。在这个工厂的具体实现中,你可以手动实例化这些视图模型,并传入它们需要的信息。

我还将从登录视图模型中删除对 shell 视图模型的引用。相反,要么使用 shell 可以订阅的标准 .NET 事件,要么查看在 Caliburn.Micro 中实现的事件聚合器(codeplex 站点上提供了一个示例),它是中介设计模式的一种实现。这将确保您的视图模型之间的良好解耦。

于 2010-12-15T14:23:14.827 回答