棱镜与mvvm光为wpf

 顺辉1988 发布于 2023-02-11 19:09

我们正在使用MVVM项目启动WPF,并且必须决定PRISM或MVVM Light(我对这两个框架都不熟悉).我已阅读了几篇文章但仍有几个问题.有人可以对框架中的以下几个方面有所了解吗?:

    性能:出于任何原因,一个框架是否会比另一个框架表现更好?

    应用程序内的通信(viewmodel到viewmodel或模块​​之间等):我已经读过MVVM Light有Messenging Service,它看起来也相当容易.但是PRISM似乎没有任何等价物.真的吗?PRISM如何处理交互?

    单元测试:已经读过PRISM更好地支持单元测试.我们还可以在MVVM Light中编写NUNIT或VSTS测试吗?

Vladimir Al.. 20

    我刚刚将一个项目从Prism转移到了MvvmLight,它看起来工作得更快(非常主观).

    Prism和MvvmLight都有Mediator实现(Prvent中的IEventAggregator,MvvmLight中的IMessenger).但与IEventAggregator相比,IMessenger具有更多功能(例如,使用令牌发送消息),使用起来更方便(参见下一项).

    MvvmLight还有一个更强大的ViewModelBase类.

    使用MvvmLight的应用程序比使用Prism的应用程序更容易测试.例如,IMessenger比IEventAggregator更容易模拟.

PrismViewModel.cs

using System;
using Microsoft.Practices.Prism.Events;
using Microsoft.Practices.Prism.ViewModel;

// An ugly empty event class
public class StringEvent : CompositePresentationEvent { }

public sealed class PrismViewModel : NotificationObject
{
    private readonly IEventAggregator _eventAggregator;

    private string _name;

    public PrismViewModel(IEventAggregator eventAggregator)
    {
        if (eventAggregator == null)
            throw new ArgumentNullException("eventAggregator");

        _eventAggregator = eventAggregator;
        _eventAggregator.GetEvent().Subscribe(s => Name = s);
    }

    public string Name
    {
        get { return _name; }
        set
        {
            // boiler-plate code
            if (value == _name) 
                return;
            _name = value;
            RaisePropertyChanged(() => Name);
        }
    }

    public void SendMessage(string message)
    {
        _eventAggregator.GetEvent().Publish(message);
    }
}

PrismViewModelTestCase.cs

using System;
using FluentAssertions;
using Microsoft.Practices.Prism.Events;
using NSubstitute;
using NUnit.Framework;

public class PrismViewModelTestCase
{
    private static PrismViewModel CreateViewModel(IEventAggregator eventAggregator = null)
    {
        // You can't return Substitute.For()
        // because it returns null when PrismViewModel's constructor
        // invokes GetEvent() method which leads to NullReferenceException
        return new PrismViewModel(eventAggregator ?? CreateEventAggregatorStub());
    }

    private static IEventAggregator CreateEventAggregatorStub()
    {
        var eventAggregatorStub = Substitute.For();
        eventAggregatorStub.GetEvent().Returns(Substitute.For());
        return eventAggregatorStub;
    }

    [Test]
    public void Constructor_WithNonNullEventAggregator_ExpectedSubscribesToStringEvent()
    {
        // Arrange
        var stringEventMock = Substitute.For();

        var eventAggregatorStub = Substitute.For();
        eventAggregatorStub.GetEvent().Returns(stringEventMock);

        // Act
        CreateViewModel(eventAggregatorStub);

        // Assert
        // With constrained isolation framework you can only mock virtual members
        // CompositePresentationEvent has only one virtual Subscribe overload with four parameters
        stringEventMock.Received()
                       .Subscribe(Arg.Any>(), Arg.Any(), Arg.Any(),
                                  Arg.Any>());
    }

    [Test]
    public void Name_ExpectedRaisesPropertyChanged()
    {
        var sut = CreateViewModel();
        sut.MonitorEvents();

        sut.Name = "any-value";

        sut.ShouldRaisePropertyChangeFor(vm => vm.Name);
    }

    [Test]
    public void SendMessage_ExpectedPublishesStringEventThroughEventAggregator()
    {
        // Arrange
        var stringEventMock = Substitute.For();

        var eventAggregatorStub = Substitute.For();
        eventAggregatorStub.GetEvent().Returns(stringEventMock);

        var sut = CreateViewModel(eventAggregatorStub);
        const string expectedPayload = "any-string-payload";

        // Act
        sut.SendMessage(expectedPayload);

        // Assert
        stringEventMock.Received().Publish(expectedPayload);
    }
}

MvvmLightViewModel.cs

using System;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Messaging;

public sealed class MvvmLightViewModel : ViewModelBase
{
    private string _name;

    public MvvmLightViewModel(IMessenger messenger)
    {
        if (messenger == null)
            throw new ArgumentNullException("messenger");

        // ViewModelBase already have field for IMessenger
        MessengerInstance = messenger; 
        MessengerInstance.Register(this, s => Name = s);
    }

    public string Name
    {
        get { return _name; }
        set { Set(() => Name, ref _name, value); // Chic!  }
    }

    public void SendMessage(string message)
    {
        MessengerInstance.Send(message);
    }
}

MvvmLightViewModelTestCase.cs

using System;
using FluentAssertions;
using GalaSoft.MvvmLight.Messaging;
using NSubstitute;
using NUnit.Framework;

public class MvvmLightViewModelTestCase
{
    private static MvvmLightViewModel CreateViewModel(IMessenger messenger = null)
    {
        return new MvvmLightViewModel(messenger ?? Substitute.For());
    }

    [Test]
    public void Constructor_WithNonNullMessenger_ExpectedRegistersToStringMessage()
    {
        var messengerStub = Substitute.For();

        var sut = CreateViewModel(messengerStub);

        messengerStub.Received().Register(sut, Arg.Any>());
    }

    [Test]
    public void Name_ExpectedRaisesPropertyChanged()
    {
        var sut = CreateViewModel();
        sut.MonitorEvents();

        sut.Name = "any-value";

        sut.ShouldRaisePropertyChangeFor(vm => vm.Name);
    }

    [Test]
    public void SendMessage_ExpectedSendsStringMessageThroughMessenger()
    {
        var messengerMock = Substitute.For();
        var sut = CreateViewModel(messengerMock);
        const string expectedMessage = "message";

        sut.SendMessage(expectedMessage);

        messengerMock.Received().Send(expectedMessage);
    }
}

棱镜的缺点:

它是非完全开源项目(官方Prism存储库是只读的)

2015-10-30:现在它是完全开源的:https://github.com/PrismLibrary/Prism

它不再积极发展

2015-10-30:新版Prism:https://github.com/PrismLibrary/Prism

直接使用它的类导致锅炉板和不太可读的代码

我认为任何新项目都应该基于现代解决方案和方法.恕我直言,任何现代MVVM框架(如Catel,Caliburn.Micro,MvvmLight,ReactiveUI)都比Prism好得多.

撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有