< Summary

Information
Class: MyNet.UI.ViewModels.Crud.ItemEditionViewModel<T>
Assembly: MyNet.UI
File(s): https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.UI/ViewModels/Crud/ItemEditionViewModel.cs
Tag: 323_28699572109
Line coverage
84%
Covered lines: 28
Uncovered lines: 5
Coverable lines: 33
Total lines: 155
Line coverage: 84.8%
Branch coverage
50%
Covered branches: 3
Total branches: 6
Branch coverage: 50%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)50%22100%
set_OriginalItem(...)100%11100%
set_IsDirty(...)100%11100%
SetOriginalItem(...)100%11100%
OnResetAsync(...)100%11100%
ResetItem()100%11100%
ApplyAsync(...)100%11100%
CloneItem(...)50%5466.66%
HandleItemChanged()100%11100%
HandleCurrentItemPropertyChanged(...)100%210%
CanReset()100%11100%
CanApply()100%11100%
UpdateIsDirty()100%11100%

File(s)

https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.UI/ViewModels/Crud/ItemEditionViewModel.cs

#LineLine coverage
 1// -----------------------------------------------------------------------
 2// <copyright file="ItemEditionViewModel.cs" company="Stéphane ANDRE">
 3// Copyright (c) Stéphane ANDRE. All rights reserved.
 4// </copyright>
 5// -----------------------------------------------------------------------
 6
 7using System;
 8using System.ComponentModel;
 9using System.Threading;
 10using System.Threading.Tasks;
 11using System.Windows.Input;
 12using FluentValidation;
 13using MyNet.Globalization.Culture;
 14using MyNet.Observable;
 15using MyNet.Observable.Validation.Validators;
 16using MyNet.UI.Commands;
 17
 18namespace MyNet.UI.ViewModels.Crud;
 19
 20/// <summary>
 21/// Provides a reusable base implementation for editable item view models.
 22/// </summary>
 23/// <typeparam name="T">The edited item type.</typeparam>
 24public abstract class ItemEditionViewModel<T> : ItemViewModel<T>, IItemEditionViewModel<T>, IEditionStateViewModel
 25{
 26    /// <summary>
 27    /// Initializes a new instance of the <see cref="ItemEditionViewModel{T}"/> class.
 28    /// </summary>
 29    /// <param name="commandFactory">Optional command factory used to create commands.</param>
 30    /// <param name="validator">Optional validator used to validate the item edition view model.</param>
 31    /// <param name="cultureService">Optional culture service used to manage culture changes.</param>
 32    protected ItemEditionViewModel(
 33        ICommandFactory? commandFactory = null,
 34        IValidator<ItemEditionViewModel<T>>? validator = null,
 35        ICultureService? cultureService = null)
 936        : base(commandFactory, cultureService)
 37    {
 938        var commands = commandFactory.GetOrDefault();
 39
 40        ApplyCommand = commands.Create(() => ApplyAsync(), CanApply);
 41
 942        this.UseTracking()
 943            .UseValidation((IValidator?)validator ?? EmptyValidator.Instance);
 944    }
 45
 46    /// <summary>
 47    /// Gets the command to apply the current changes.
 48    /// </summary>
 49    public ICommand ApplyCommand { get; }
 50
 51    /// <summary>
 52    /// Gets the original item snapshot.
 53    /// </summary>
 54    public T? OriginalItem
 55    {
 56        get;
 1257        private set => SetProperty(ref field, value);
 58    }
 59
 60    /// <summary>
 61    /// Gets a value indicating whether the edited item differs from the original snapshot.
 62    /// </summary>
 63    public bool IsDirty
 64    {
 65        get;
 3666        private set => SetProperty(ref field, value);
 67    }
 68
 69    /// <summary>
 70    /// Sets the original item and initializes the current editable item from it.
 71    /// </summary>
 72    /// <param name="item">The original item.</param>
 73    public virtual void SetOriginalItem(T? item)
 74    {
 975        OriginalItem = CloneItem(item);
 976        SetItem(CloneItem(item));
 977        UpdateIsDirty();
 978    }
 79
 80    /// <summary>
 81    /// Restores the current item from the original snapshot asynchronously.
 82    /// </summary>
 83    /// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
 84    /// <returns>A task that represents the asynchronous operation.</returns>
 85    protected override Task OnResetAsync(CancellationToken cancellationToken = default)
 86    {
 387        ResetItem();
 388        UpdateIsDirty();
 89
 390        return Task.CompletedTask;
 91    }
 92
 93    /// <summary>
 94    /// Restores the current item from the original snapshot.
 95    /// </summary>
 396    protected virtual void ResetItem() => SetItem(CloneItem(OriginalItem));
 97
 98    /// <summary>
 99    /// Applies the changes to the item. By default, it updates the original snapshot with the current item state and re
 100    /// </summary>
 101    /// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
 102    /// <returns>A task that represents the asynchronous operation.</returns>
 103    public virtual Task ApplyAsync(CancellationToken cancellationToken = default)
 104    {
 3105        OriginalItem = CloneItem(Item);
 3106        UpdateIsDirty();
 107
 3108        return Task.CompletedTask;
 109    }
 110
 111    /// <summary>
 112    /// Creates an editable copy of the specified item.
 113    /// </summary>
 114    /// <param name="item">The item to clone.</param>
 115    /// <returns>A copy suitable for edition, or the original instance when cloning is not available.</returns>
 116    protected virtual T? CloneItem(T? item)
 24117        => item switch
 24118        {
 0119            null => default,
 0120            ICloneable cloneable => (T?)cloneable.Clone(),
 24121            _ => item
 24122        };
 123
 124    /// <inheritdoc />
 125    protected override void HandleItemChanged()
 126    {
 21127        base.HandleItemChanged();
 21128        UpdateIsDirty();
 21129    }
 130
 131    /// <inheritdoc />
 132    protected override void HandleCurrentItemPropertyChanged(PropertyChangedEventArgs e)
 133    {
 0134        base.HandleCurrentItemPropertyChanged(e);
 0135        UpdateIsDirty();
 0136    }
 137
 138    /// <summary>
 139    /// Determines whether the item can be reset.
 140    /// </summary>
 141    /// <returns><see langword="true"/> when the item can be reset; otherwise <see langword="false"/>.</returns>
 3142    protected override bool CanReset() => IsDirty;
 143
 144    /// <summary>
 145    /// Determines whether the changes can be applied.
 146    /// </summary>
 147    /// <returns><see langword="true"/> when changes can be applied; otherwise <see langword="false"/>.</returns>
 3148    protected virtual bool CanApply() => IsDirty;
 149
 150    /// <summary>
 151    /// Recomputes the dirty state.
 152    /// </summary>
 36153    protected void UpdateIsDirty() => IsDirty = !Equals(Item, OriginalItem);
 154}
 155