c# - 更改基本 MVVM 的当前实现以遵守 SOLID 模式

标签 c# wpf mvvm solid-principles command-query-separation

我一直在使用在线提供的 MVVM 示例中通常提到的基本设计模式编写我所有的 MVVM 应用程序。我遵循的模式如下所述:

型号

本节包括 DTO 类及其属性和接口(interface) IDataService 等:

 public class Employee
 {
   public string EmployeeName { get; set; }
   public string EmployeeDesignation { get; set; }
   public string EmployeeID { get; set; }
 }

public interface IDataService
{
  public Task<Employee> GetEmployeeLst();
}

代理

该层包含实现 IDataservice 的 Dataservice 调用,例如:
public class DataService : IDataService
{
   public async Task<Employee> GetEmployeeLst()
   {
     // Logic to get employee data from HTTPClient call
   }
}

查看型号

该层包含 ViewModel 以及对从中接收所有数据的模型和代理层的引用:
public class BaseViewModel
{
    public BaseViewModel(INavigationService nav, IDataService data, IAESEnDecrypt encrypt, IGeoLocationService geoLocation, IMessageBus msgBus, ISmartDispatcher smtDispatcher)
    {
    }

    // This also include common methods and static properties that are shared among most of the ViewModels
}

所有的 ViewModel 都继承 BaseViewModel。每个 viewModel 还包含在 UI 触发事件时执行的 Delegatecommand。然后,它通过在代理层调用 DataService 从服务器获取数据并执行业务逻辑并填充绑定(bind)到 View 的 ViewModel 中的属性。对于每个 View,都有一个绑定(bind)到 View 的 Datacontext 的 VM。
ViewModel 还负责启动我使用触发器启动 Storyboard的动画,该 Storyboard绑定(bind)到我在 VM 中的枚举以更改这些触发器的状态,例如:http://www.markermetro.com/2011/05/technical/mvvm-friendly-visual-state-management-with-windows-phone-7/

查看

在这一层中,我拥有所有 View 、用户控件和业务逻辑,并实现了某些依赖项,例如 GeoLocation 服务、AES 加密、 View 之间的 NavigationService 等。

每个 View 都有 .xaml 和 .xaml.cs 文件。在 .xaml.cs 文件中,我将 View 的数据上下文与 VM 绑定(bind),如下所示:
this.DataContext = App.IOConatiner.GetInstance<DashboardViewModel>();

从这里开始,所有的绑定(bind)都会发生。

我的问题是,最近我知道这种模式没有遵循我在回答我的问题时了解到的 SOLID 设计模式:
Simple Injector inject multiple dependency in BaseClass

我正在努力按照我之前的问题答案中给出的建议来改变我的设计。但我无法得到一些东西,比如:
  • 当前 View Datacontext 绑定(bind)到 ViewModel,因此所有控件都由 VM 中的属性控制。我将如何使用处理器/服务或 DialogHandler 将其更改为上述模式?
  • 我正在使用绑定(bind)到 UI 元素的命令属性的委托(delegate)命令。执行这些命令会发生某些 Action ,例如动画,显示用户控件。如何在命令模式中做到这一点?
  • 我怎样才能开始改变我当前的实现,以用最好的方法来适应所有这些变化?
  • 最佳答案

    首先回答你的问题3

    How can I start changing my current implementation to accommodate all those changes with best possible approach?



    这是您需要采取的第一步。这不是对当前代码进行一些智能重构的情况。您将需要退后一步并设计应用程序。我曾经读过一些不错的blog关于(重新)设计。

    在开始编写任何代码之前,定义您希望向用户显示多少种不同的基本类型的 View ?例如。:
  • 只需显示(任何类型的)数据
  • 编辑资料
  • 提醒用户
  • 询问用户输入
  • ...

  • 当您定义了不同的需求时,您可以将其转换为针对它们所服务的工作量身定制的特定界面。例如,允许用户编辑数据的 View 通常具有如下界面:
    public interface IEditViewModel<TEntity>
    {
        public EditResult<TEntity> EditEntity(TEntity entityToEdit)();
    }
    

    一旦你把这个设计的每一个细节都做好了,你必须决定如何向用户展示你的观点。我为此使用了另一个接口(interface)来为我处理此任务。但您也可以决定让导航服务处理此类任务。

    有了这个框架,您就可以开始编写您的实现了。

    Currently View Datacontext is binded to ViewModel hence all the controls are controlled by a property in VM. How would I change this to your above mentioned pattern with Processor/Service or DialogHandler?



    这在本设计中不会改变。您仍然会将您的 View 绑定(bind)到您的 View 模型并将数据上下文设置为 View 模型。对于很多 View ,使用像 Caliburn Micro 这样的 MVVM 框架会派上用场。根据 Convention over Configuration,这将为您完成很多 MVVM 工作。 .从这个模型开始,会使学习曲线更高,所以我的建议是从手工开始。您将通过这种方式了解在此类 MVVM 工具的保护下会发生什么。

    I am using Delegatecommands which are binded to command property of UI element. Execution of these command certain action happens like animation, usercontrol is displayed. How to do it in command pattern?



    我不确定您在这里提到的命令模式是否是 command pattern我在上一个答案中告诉过你。如果是这样,我认为您需要重新阅读此博客,因为这与我认为您在此问题中所指的命令完全无关。

    动画之类的东西是 View 的责任,而不是 View 模型。所以 View 应该处理所有这些东西。 XAML 有很多方法可以处理这个问题。在这里我无法解释。一些想法:Triggers , Dependency Properties

    另一种选择:代码后面!如果逻辑纯粹是与 View 相关的 IMO,则将此代码放在 View 后面的代码中并不是致命的罪过。只是不要急于做一些灰色地带的事情!

    对于仅在 View 模型中执行方法调用的命令,仍然可以使用 ICommand,并且像 Caliburn 这样的 MVVM 工具会自动执行此操作...

    仍然:松开基类....

    关于c# - 更改基本 MVVM 的当前实现以遵守 SOLID 模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28398363/

    相关文章:

    c# - 为什么我们应该使用临时对象来引发事件?

    c# - 如果文本超出文本 block 的边界,则更改字体大小

    c# - 简单的 Mvvm 数据绑定(bind) - xamarin 表单

    wpf - MVVM Light 和 MVVM 有什么区别?

    c# - 为什么这个 ListView CheckBox 绑定(bind)到整个 View 模型而不是行项目?

    c# - ToolStripMenuItem 背景图像在鼠标悬停时消失(.net winforms)

    c# - 如何将 .ico 文件与编译后的 .exe 文件合并?

    c# - 将事件解决方案平台从任何 CPU 更改为 x86 时,WPF 应用程序未启动

    c# - 您如何获得 IsolatedStorage 中所有文件的平面列表?

    c# - 共享文件夹API