改变当前执行的基本MVVM的坚持实型 [英] Change current implementation of basic MVVM to adhere to SOLID pattern

查看:233
本文介绍了改变当前执行的基本MVVM的坚持实型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在写,在MVVM例子普遍提及的在网上提供基本的设计模式,我所有的MVVM应用程序。那我下面的模式描述如下:



型号



本节包括DTO类以及它们的属性和接口IDataService和这样的:

 公共类Employee 
{
公共字符串EmployeeName {搞定;组; }
公共字符串EmployeeDesignation {搞定;组; }
公共字符串雇员{搞定;组; }
}

公共接口IDataService
{
公共任务<员工> GetEmployeeLst();
}



代理



这层包含的DataService调用它们实现IDataservice这样的:

 公共类的DataService:IDataService 
{
公共异步任务<员工> GetEmployeeLst()
{
//逻辑从中获取员工数据调用了HTTPClient
}
}

视图模型



这层包含视图模型和参考模型和代理层的所有数据好评:

 公共类BaseViewModel 
{
公共BaseViewModel(INavigationService导航,IDataService数据,IAESEnDecrypt加密, IGeoLocationService地理位置,IMessageBus msgBus,ISmartDispatcher smtDispatcher)
{
}

//这也包括普通的方法和被中大部分的ViewModels
的共享}静态属性

所有视图模型继承BaseViewModel。每个视图模型还包含Delegatecommand其UI时触发一个事件被执行。然后通过在代理层调用的DataService取来自服务器的数据并执行业务逻辑,并填充其绑定到视图中视图模型的属性。对于每一个观有其绑定到View的DataContext的虚拟机。
视图模型还负责开始我用的触发启动它绑定到我的枚举VM为这些触发器的状态变化为例,在分镜动画:的 http://www.markermetro.com/2011/05/technical/ MVVM友好的可视状态管理,与窗口电话-7 /



查看



在这层我有我的所有视图,用户控件和业务逻辑与实现一定的依赖性像地理定位服务,AES加密,访问量等之间的NavigationService的。



每个视图都有的.xaml和.xaml.cs文件。在.xaml.cs文件我已经绑定与VM的观点是这样的数据上下文:

  this.DataContext =应用。 IOConatiner.GetInstance< D​​ashboardViewModel>(); 

和从这里所有具有约束力的发生。



我的问题是,最近我有知识,这种模式是不跟随雄厚的设计模式,我得到了知道这个答案我的问题:
简单注射器注入在BaseClass的多依赖



我拼命的改变我的设计按在我刚才的问题的回答给出的建议。但我不能够得到一些东西,如:




  1. 目前视图的DataContext被绑定到视图模型,因此所有的控制都是通过在虚拟机中的属性控制。我将如何改变这种与处理器/服务或DialogHandler中的上述模式?


  2. 我使用Delegatecommands这是绑定到命令的UI元素的属性。这些命令的某些行动的执行偏偏喜欢动画,显示用户控件。如何做到在命令模式?


  3. 我如何开始改变我目前的执行,以容纳所有那些最好的办法改变?



解决方案

$ b的>第一$ b

我如何开始改变我目前的执行,以容纳所有那些最好的办法改变?




这是你需要采取的第一步。这是不是你当前的代码的一些聪明的重构的情况。您将需要退后一步并设计应用程序。我曾经看到过一些不错的博客了解(重新)设计。



在开始编写任何代码之前,确定你会想有多少种不同的基本类型的视图来显示给用户?例如:




  1. 只显示(任何类型)的数据

  2. 编辑数据

  3. 警报用户

  4. 要求用户输入

  5. ...



当你定义了不同的要求,可以翻译这是他们所服务的工作量身定做特定的接口。例如,让用户编辑数据的视图通常具有一个接口,看起来是这样的:

 公共接口IEditViewModel< TEntity> ; 
{
公共EditResult< TEntity> EditEntity(TEntity entityToEdit)();
}



一旦这个设计到位的每一个细节,你必须决定你将如何表明你的观点给用户。我用另一种功能,这来处理这个任务给我。但你也可以决定让导航服务处理这类任务。



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




目前查看的DataContext被绑定到视图模型因此所有控制由虚拟机中的一个属性控制。我将如何改变这种与处理器/服务或DialogHandler中的上述模式?




这不会在本设计中改变。你仍然会视图绑定到你的视图模型,并设置在DataContext到视图模型。随着大量的意见像使用微卡利的MVVM框架会派上用场。这会做很多的东西MVVM为你的基础上,惯例优于配置。要开始使用这种模式,就会使学习曲线甚至更高,所以我建议用手工启动。您将学习这种方式这样一个MVVM工具,在幕后发生了什么。




我使用Delegatecommands这是绑定到命令的UI特性元件。这些命令的某些行动的执行偏偏喜欢动画,显示用户控件。如何做到在命令模式?




我不知道,如果你在这里提到的命令模式是的 我劝你在以前的答案命令模式。如果是这样,我认为你需要重读这篇博客,因为这是完全无关的,我认为你这个问题的意思是命令。



动漫之类的东西视图,而不是视图模型的责任。因此认为应该处理这一切的东西。 XAML有很多的方式来处理这个问题。比我更可以在这里解释一下。一些想法:触发器 依赖属性



另一种选择:代码后面!如果逻辑视图纯粹国际海事组织有关它不是一个不可饶恕的大罪来放置这些代码在代码视图的后面。只要不被temped做一些灰色地带的东西!



有关,只是在你的视图模型执行方法调用命令的ICommand仍然是可能的,MVVM工具,如将卡利这样做自动的...



和依然:宽松的基类....


I have been writing all my MVVM application with basic design pattern generally mentioned in MVVM examples available online. The pattern that I am following is described below:

Model

This section include DTO classes with their properties and Interfaces IDataService and like:

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

Proxy

This layer contains Dataservice calls which implement IDataservice like:

public class DataService : IDataService
{
   public async Task<Employee> GetEmployeeLst()
   {
     // Logic to get employee data from HTTPClient call
   }
}

ViewModel

This layer contains ViewModel and reference to Model and Proxy layer from which all data is received:

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
}

All the ViewModel inherits BaseViewModel. Each viewModel also contains Delegatecommand which is executed when UI triggers an event. Which then fetches the data from the server by calling DataService in proxy layer and perform business logic and populates the properties in ViewModel which is binded to the view. For each View there is a VM which is binded to the Datacontext of the View. ViewModel is also responsible for starting an animation I have used trigger to start storyboard which is binded to my enums in VM for state change of these trigger as in example in: http://www.markermetro.com/2011/05/technical/mvvm-friendly-visual-state-management-with-windows-phone-7/

View

In this layer I have all my Views, Usercontrols and business logic with implementation of certain dependencies like GeoLocation Service, AES encryption, NavigationService between Views etc.

Every View has .xaml and .xaml.cs file. In .xaml.cs file I have binded the data context of the view with VM like this:

this.DataContext = App.IOConatiner.GetInstance<DashboardViewModel>();

and from here on all binding happens.

My problem is that recently I had the knowledge that this pattern is not following a SOLID design pattern which I got know in this answer of my question: Simple Injector inject multiple dependency in BaseClass

I am trying very hard to change my design as per the suggestion given in my previous question's answer. But I am not able to get some of the things like:

  1. 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?

  2. 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?

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

解决方案

First of all an answer to your question 3

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

This is the very first step you need to take. It is not a case of some smart refactoring of your current code. You will need to take a step back and design the application. I once read some nice blog about (re)design.

Before starting to write any code, define how many different basic types of views you will want to show to the user? E.g.:

  1. Just show (any type of) data
  2. Edit data
  3. Alert user
  4. Ask user for input
  5. ...

When you defined your different requirements, you can translate this to specific interfaces that are tailor made for the job they serve. For example a view that lets the user edit data will typically have an interface that will look something like:

public interface IEditViewModel<TEntity>
{
    public EditResult<TEntity> EditEntity(TEntity entityToEdit)();
}

Once you every detail of this design in place, you must decide how you will show your views to the user. I used another interface for this to handle this task for me. But you could also decide to let a navigation service handle this kind of task.

With this framework in place, you can start coding your implementations.

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?

This will not change in this design. You will still bind your view to your viewmodel and set the datacontext to the viewmodel. With a lot of views the use of an MVVM framework like Caliburn Micro will come in handy. This will do a lot of the MVVM stuff for you, based on Convention over Configuration. To start with this model, would make the learning curve even higher, so my advice to start of by hand. You will learn this way what happens under the covers of such an MVVM tool.

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?

I'm not sure if the command pattern you mention here is the command pattern I advised you in the previous answer. If so, I think you need to reread this blog, because this is totally unrelated to the commands I think you mean in this question.

Animation and that sort of stuff is the responsibility of the view, not the viewmodel. So the view should handle all this stuff. XAML has a lot of ways to handle this. More than I can explain here. Some ideas: Triggers, Dependency Properties

Another option: Code behind! If the logic is purely view related IMO it is not a mortal sin to place this code in the code behind of your view. Just don't be temped to do some gray area stuff!

For commands that just perform a method call in your viewmodel, ICommand is still possible and MVVM tools like Caliburn will do this automagically...

And still: Loose the base class....

这篇关于改变当前执行的基本MVVM的坚持实型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆