wpf wpf的棱镜与mvvm灯

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20487243/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 00:01:26  来源:igfitidea点击:

prism vs mvvm light for wpf

wpfmvvmprismmvvm-light

提问by Padmaja

We are starting a WPF with MVVM project and have to decide on PRISM or MVVM Light (I am new to both these frameworks). I have read through a few posts but still have a few questions. Can someone please throw some light on the following aspects w.r.t. both the frameworks?:

我们正在启动一个带有 MVVM 项目的 WPF,并且必须决定是 PRISM 还是 MVVM Light(我对这两个框架都不熟悉)。我已经阅读了一些帖子,但仍有一些问题。有人可以对这两个框架的以下方面有所了解吗?:

  1. Performance: Will either one framework perform better than the other for any reason?

  2. Communication within the app (viewmodel to viewmodel or between modules etc): I have read that MVVM Light has Messenging Service which appears to be fairly easy as well. But PRISM does not appear to have any equivalent. Is that true? How would PRISM handle interactions?

  3. Unit Testing: Have read that PRISM supports Unit Testing better. Can we still write NUNIT or VSTS tests in MVVM Light also?

  1. 性能:出于某种原因,一个框架的性能会比另一个更好吗?

  2. 应用程序内的通信(视图模型到视图模型或模块之间等):我读过 MVVM Light 有消息服务,这似乎也相当容易。但 PRISM 似乎没有任何等价物。真的吗?PRISM 将如何处理交互?

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

回答by Vladimir Almaev

  1. I just moved a project from Prism to MvvmLight and it seems to work faster (very subjective).

  2. Both Prism and MvvmLight have Mediator realisation (IEventAggregator in Prism, IMessenger in MvvmLight). But IMessenger has more abilities (for instance, sending messages with tokens) compared to IEventAggregator and is much more convenient to use (see next item).

    MvvmLight also has a more powerful ViewModelBase class.

  3. Applications that use MvvmLight are much easier to test than those that use Prism. For instance, IMessenger is easier to mock than IEventAggregator.

  1. 我刚刚将一个项目从 Prism 转移到 MvvmLight,它似乎工作得更快(非常主观)。

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

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

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

PrismViewModel.cs

棱镜视图模型.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

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

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

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);
    }
}

Disadvantages of Prism:

棱镜的缺点:

I think that any new project should be based on modern solutions and approaches. IMHO, any modern MVVM-framework (like Catel, Caliburn.Micro, MvvmLight, ReactiveUI) is much better than Prism.

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

回答by Ricardo de Assuncao Goncalves

You cannot fully compare Prism and MvvmLight.

您无法完全比较 Prism 和 MvvmLight。

Prism is more about application architecture even though Prism has been known as MVVM framework. Actually until Prism 5 it had nothing to do with MVVM and It didn't have BaseViewModel class in Prism 4.1 and in prior.

尽管 Prism 被称为 MVVM 框架,但它更多地是关于应用程序架构的。实际上,在 Prism 5 之前,它与 MVVM 无关,并且在 Prism 4.1 和更早版本中没有 BaseViewModel 类。

Prism is not a MVVM framework it is application framework it sits higher than that. Prism 5 introduced some support for MVVM and Prism 6 took it futher.

Prism 不是一个 MVVM 框架,它是一个高于它的应用程序框架。Prism 5 引入了对 MVVM 的一些支持,Prism 6 进一步支持。

MVVM is just another aspect of problems that prism provides guidance to solve.

MVVM 只是prism 提供指导解决问题的另一个方面。

It is like comparing Angular vs. Knockout. AngularJS manages the whole application and defines guidelines on how the application code should be structured, whereas with KnockoutJS the application structure is entirely up to you. It is a similar case between Prism and MvvmLight.

这就像比较 Angular 与 Knockout。AngularJS 管理整个应用程序并定义应用程序代码的结构指南,而使用 KnockoutJS,应用程序结构完全取决于您。Prism 和 MvvmLight 之间的情况类似。

Prism provides an implementation of a collection of design patterns that are helpful in writing well structured and maintainable XAML applications, including MVVM, dependency injection, commanding, event aggregation, and more. Prism's core functionality is a shared code base in a Portable Class Library targeting these platforms; WPF, Windows 10 UWP, and Xamarin Forms.

Prism 提供了一组设计模式的实现,这些模式有助于编写结构良好且可维护的 XAML 应用程序,包括 MVVM、依赖注入、命令、事件聚合等。Prism 的核心功能是针对这些平台的可移植类库中的共享代码库;WPF、Windows 10 UWP 和 Xamarin 表单。

I would recommend to use Prism if you are developing an enterprise level application using wpf.

如果您正在使用 wpf 开发企业级应用程序,我建议您使用 Prism。

Please watch this Webinar about MVVM Made Simple with Prism. The presenter is Brian Lagunas: https://www.youtube.com/watch?v=ZfBy2nfykqY

请观看有关使用 Prism 简化 MVVM 的网络研讨会。主持人是 Brian Lagunas:https: //www.youtube.com/watch?v=ZfBy2nfykqY

回答by John Blacker

I don't believe MS has ever promoted PRISM as a "framework" in the same sense that MVVM Light, Caliburn, etc. are "advertised." My understanding is the PRISM was always presented to the "world" as a "practice." Which, I believe, simply means a organized way of building applications. It becomes a bit confusing because of all the code that is supplied with PRISM and one can consider it a "framework" that can be used to build applications. And, it's true, you can use the code that is supplied with PRISM to build applications of your own. But, PRISM, in my mind is much more complicated than the "frameworks" that are available for MVVM and there is a steep learning curve as well as the possibility of "overkill" and making your application more complex than is necessary. If you have the time to learn the latest "framework" or "practice" at the time you are building your application, that's GREAT! My experience has been that I don't have the luxury of factoring in learning some new "practice" or the latest "framework" but have to get the job done. In an ideal world, one would like to be able to use the latest and greatest "framework" or employ the latest "practices" but sometimes you just have to stick with what you already know and get it done.

我不相信 MS 曾将 PRISM 宣传为“框架”,就像 MVVM Light、Caliburn 等被“宣传”一样。我的理解是棱镜总是作为一种“实践”呈现给“世界”。我相信,这只是一种有组织的构建应用程序的方式。由于 PRISM 提供了所有代码,因此它变得有点混乱,人们可以将其视为可用于构建应用程序的“框架”。而且,的确,您可以使用 PRISM 提供的代码来构建您自己的应用程序。但是,在我看来,PRISM 比可用于 MVVM 的“框架”复杂得多,而且学习曲线陡峭,并且有可能“矫枉过正”并使您的应用程序比必要的更复杂。如果您在构建应用程序时有时间学习最新的“框架”或“实践”,那就太好了!我的经验是,我没有精力去学习一些新的“实践”或最新的“框架”,但必须完成工作。在理想的世界中,人们希望能够使用最新最好的“框架”或采用最新的“实践”,但有时您只需要坚持已经知道的事情并完成它。但必须完成工作。在理想的世界中,人们希望能够使用最新最好的“框架”或采用最新的“实践”,但有时您只需要坚持已经知道的事情并完成它。但必须完成工作。在理想的世界中,人们希望能够使用最新最好的“框架”或采用最新的“实践”,但有时您只需要坚持已经知道的事情并完成它。