gpt4 book ai didi

wpf - wpf的 Prism vs mvvm灯

转载 作者:行者123 更新时间:2023-12-03 10:01:43 27 4
gpt4 key购买 nike

我们正在使用 MVVM 项目启动 WPF,并且必须决定使用 PRISM 或 MVVM Light(我对这两个框架都是新手)。我已经阅读了一些帖子,但仍有一些问题。有人可以对以下方面进行一些说明吗?两个框架?:

  • 性能:无论出于何种原因,任何一个框架都会比另一个框架表现得更好吗?
  • 应用程序内的通信(viewmodel 到 viewmodel 或模块之间等):我读过 MVVM Light 有消息服务,这似乎也相当容易。但 PRISM 似乎没有任何等价物。真的吗? PRISM 将如何处理交互?
  • 单元测试:已阅读 PRISM 更好地支持单元测试。我们还能在 MVVM Light 中编写 NUNIT 或 VSTS 测试吗?
  • 最佳答案

  • 我刚刚将一个项目从 Prism 转移到 MvvmLight,它似乎工作得更快(非常主观)。
  • Prism 和 MvvmLight 都有 Mediator 实现(Prism 中的 IEventAggregator,MvvmLight 中的 IMessenger)。但与 IEventAggregator 相比,IMessenger 具有更多功能(例如,使用 token 发送消息)并且使用起来更加方便(参见下一项)。

    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<string> { }

    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<StringEvent>().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<StringEvent>().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<IEventAggregator>()
    // because it returns null when PrismViewModel's constructor
    // invokes GetEvent<StringEvent>() method which leads to NullReferenceException
    return new PrismViewModel(eventAggregator ?? CreateEventAggregatorStub());
    }

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

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

    var eventAggregatorStub = Substitute.For<IEventAggregator>();
    eventAggregatorStub.GetEvent<StringEvent>().Returns(stringEventMock);

    // Act
    CreateViewModel(eventAggregatorStub);

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

    [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<StringEvent>();

    var eventAggregatorStub = Substitute.For<IEventAggregator>();
    eventAggregatorStub.GetEvent<StringEvent>().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<string>(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<IMessenger>());
    }

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

    var sut = CreateViewModel(messengerStub);

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

    [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<IMessenger>();
    var sut = CreateViewModel(messengerMock);
    const string expectedMessage = "message";

    sut.SendMessage(expectedMessage);

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

    Prism 的缺点:
  • 它不是完全开源的项目(官方 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 好得多。

    关于wpf - wpf的 Prism vs mvvm灯,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20487243/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com