Процессор для обработки общих команд


Я пытаюсь реализовать бизнес-логики на основе понятия команды и обработчиков команд.

Команда-это то, что содержит входные параметры для выполнения некоторых действий, и он знает, какие результаты эти действия должны производить. Обработчик команд содержит логику для выполнения действия: он принимает команды в качестве параметра, обрабатывает его определенным образом, и (в случае успеха) создает объект вывода.

public interface ICommand<TResultData>
{ }

public interface ICommandHandler<TCommand, TResultData>
    where TCommand : ICommand<TResultData>
{    
    CommandResult<TResultData> Handle(TCommand command);
}

public static class CommandProcessor
{
    public static CommandResult<TResultData> Process<TCommand, TResultData>(TCommand command)
        where TCommand : ICommand<TResultData>
    {
        var handler = ServiceLocator.GetInstance<ICommandHandler<TCommand, TResultData>>();
        return handler.Handle(command);
    }
}
public class CommandResult<TResultData>
{
    public bool Success { get; set; }

    public string Error { get; set; }

    public TResultData Data { get; set; }
}

Пример использования:

// CreateUserCommand & handler implementations *very* simplified
public class CreateUserCommand : ICommand<User>
{
    public string Email { get; set; }
}

public class CreateUserCommandHandler : ICommandHandler<CreateUserCommand, User>
{
    private readonly IRepository repository;
    public CreateUserCommandHandler (IRepository repository)
    {
        this.repository = repository;
    }
    public CommandResult<User> Handle(CreateUserCommand command)
    {
        if(this.repository.Users.Any(u=>u.Email == command.Email)
          return new CommandResult<User> { Success = false, Error = "Email already taken"};
        var user = new User {Email = command.Email};
        this.repository.Users.Add(user);
        return new CommandResult<User> { Success = true, Data = user};
    }
}

// command usage in application code
var command = new CreateUserCommand { Email = "some.email.com" };
CommandResult<User> result = CommandProcessor.Process(command);
if(result.Success)
{
    // at this point we know that result.Data is of type User, which is nice
    // so we can use this strictly-typed result data in any way
    User createdUser = result.Data;
    Console.Writeline("Created user with Id = " + createdUser.Id);
}
else
{
    Console.Writeline("Error creating user: " + result.Error);
}

Все работает довольно хорошо, как вы можете видеть в Примере, но одна вещь беспокоит меня-это пустой интерфейс ICommand. Разве плохо здесь? Может ли код быть переработан в некотором роде, чтобы сделать его лучше?



Комментарии