WPF MVVM Refactoring for Better Auditability

I have inherited a functional but confusing WPF MVVM application. To my annoyance, there have been virtually no single tests that make the adoption of MVVM somewhat pointless. So I decided to add some of them.

After grasping low-hanging fruit, I begin to run into trouble. There is a lot of interdependent code, especially inside the properties and methods that are used in views. For example, for a single call, you can specify a chain of events "change of properties", which, in turn, cause other calls, etc.

This is very difficult to verify because you have to write huge layouts and set up a large number of properties to test individual functions. Of course, you only need to do this once per class, and then reuse your layout and ViewModel for each test. But this is still a pain, and it seems to me that this is the wrong way. It would be better, of course, to try to break the code and make it more modular.

I'm not sure how realistic this is in MVVM. And I'm in a vicious circle, because without good tests, I worry about breaking the assembly with refactoring to write good tests. The fact that WPF MVVM is an additional concern because nothing tracks the relationship between View and ViewModel - a careless name change can completely break something.

I work in C # VS2013 and grabbed a trial version of ReSharper to see if it helps. This is fun to use, but so far it is not. My unit testing experience is small.

So - how can I approach this reasonably, methodically and safely? And how can I use my existing tools (and look at any other tools) to help?

+5
source share
1 answer
  • Start at the heart - business logic

Your application solves some of the problems of the real world, and this is what business logic is. The models of your view wrap these components of the business logic, even if they (components) do not yet exist (as separate classes).

As a result, you should assume that the view model is a lightweight, data preparation / redistribution object. All heavy lifting must be done inside business logic objects. The viewing model should be filed with raw data, the display is ready.

  1. modularizes

Given this important assumption (VM = no BL), move the business logic components to separate possibly modular projects. BL organization in a modular way often leads to a project structure similar to:

  • Company.Project.Feature.Contract - interfaces, entities, DTO related to the function
  • Company.Project.Feature - contract implementation
  • Company.Project.Feature.Tests - tests for implementing functions

Your goal with C # 1 and # 2 is to reach a state where dropping WPF and replacing it with the console interface only requires using the input console interface and connecting it using the BL layer. All WPF-related (Views, ViewModels) can be deleted with deletion, and such an action should not violate anything.

  1. IoC for verification.

Get familiar with dependency injection and resumes where necessary. Introduce the IoC container. Do not force your code to rely on implementation , rely on the contract . Whenever the view model takes a dependency on a BL implementation, replace it with a BL abstraction. This will be one of the necessary steps to verify the tested models.

This is how I get started. This is by no means an exhausive list, and I am convinced that you will encounter situations where sticking to it will not be enough. But what is it - working with outdated code is not an easy task.

+4
source

Source: https://habr.com/ru/post/1205944/


All Articles