Refactoring a C # Save Command Handler

I have the following command handler. The handler takes the command object and uses its properties to create or update the object.

He solves this with a property Idin the command object, which is null. If null, then create, if not, then update.

public class SaveCategoryCommandHandler : ICommandHandler<SaveCategoryCommand>
{
    public SaveCategoryCommandHandler(
        ICategoryRepository<Category> categoryRepository,
        ITracker<User> tracker,
        IMapProcessor mapProcessor,
        IUnitOfWork unitOfWork,
        IPostCommitRegistrator registrator)
    {
         // Private fields are set up. The definitions for the fields have been removed for brevity.
    }

    public override void Handle(SaveCategoryCommand command)
    {
        // The only thing here that is important to the question is the below ternary operator.

            var category = command.Id.HasValue ? GetForUpdate(command) : Create(command);

 // Below code is not important to the question. It is common to both create and update operations though.

            MapProcessor.Map(command, category);

            UnitOfWork.Commit();

            Registrator.Committed += () =>
            {
                command.Id = category.Id;
            };

    }

    private Category GetForUpdate(SaveCategoryCommand command)
    {
        // Category is retrieved and tracking information added
    }

    private Category Create(SaveCategoryCommand command)
    {
        // Category is created via the ICategoryRepository and some other stuff happens too.
    }
}

I had two handlers: one for creating and one for updating, as well as two commands for creating and updating. Everything was connected using IoC.

After refactoring into one class, to reduce the amount of code duplication, I ended up above the handler class. Another motivation for refactoring was to avoid having two commands (UpdateCategoryCommand and CreateCategoryCommand), which led to more duplication with validation and similar.

, ( Id). , , .

, refactored.

- . , . if - .

- - . - ICategoryHelper Create Update. , ICategoryRepository ITracker ICategoryHelper.

, IoC , Id .

SimpleInjector , .

IoC , ?

- ? , , , .

+4
2

, (SaveCategoryCommand UpdateCategoryCommand) ( ).

CategoryCommandBase, , , DTO, ( ). , .

[Permission(Permissions.CreateCategories)]
class SaveCategory {
    [Required, ValidateObject]
    public CategoryData Data;

    // Assuming name can't be changed after creation
    [Required, StringLength(50)]
    public string Name;
}

[Permission(Permissions.ManageCategories)]
class UpdateCategory {
    [NonEmptyGuid]
    public Guid CategoryId;

    [Required, ValidateObject]
    public CategoryData Data;
}

class CategoryData {
    [NonEmptyGuid]
    public Guid CategoryTypeId;
    [Required, StringLength(250)]
    public string Description;
}

, , , ( , , ). , . .

class CategoryCommandHandler :
    ICommandHandler<SaveCategory>,
    ICommandHandler<UpdateCategory> {
    public CategoryCommandHandler() { }

    public void Handle(SaveCategory command) {
        var c = new Category { Name = command.Name };
        UpdateCategory(c, command.Data);
    }

    public void Handle(UpdateCategory command) {
        var c = this.repository.GetById(command.CategoryId);
        UpdateCategory(c, command.Data);
    }

    private void UpdateCategory(Category cat, CategoryData data) {
        cat.CategoryTypeId = data.CategoryDataId;
        cat.Description = data.Description;
    }
}

, CRUDy , , . , requiremwnt , . , UX, , . CRUDY; , .

+6

, , . CreateCategory UpdateCategory (, ). , . , "Handle" , "Handle":

public abstract class %YOUR_NAME%CategoryBaseCommandHandler<T> : ICommandHandler<T>
{
    public override void Handle(T command)
    {
        var category = LoadCategory(command);
        MapProcessor.Map(command, category);

        UnitOfWork.Commit();

        Registrator.Committed += () =>
        {
            command.Id = category.Id;
        };
    }

    protected abstract Category LoadCategory(T command);
} 

LoadCategory.

0

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


All Articles