Processor for handling generic commands
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
2
down vote
favorite
I'm trying to implement business logic layer based on concepts of commands and command handlers.
A command is a thing that contains input parameters for executing some action, and it knows what kind of output that action should produce. A command handler contains logic for actually executing an action: it accepts a command as a param, handles it in some way, and (if successful) produces an output object.
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;
Example usage:
// 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);
Everything works pretty nice, as you can see in the usage example, but one thing that bothers me is the empty interface ICommand
. Is it a bad thing here? Can the code be refactored in some way to make it better?
c# object-oriented generics interface
add a comment |Â
up vote
2
down vote
favorite
I'm trying to implement business logic layer based on concepts of commands and command handlers.
A command is a thing that contains input parameters for executing some action, and it knows what kind of output that action should produce. A command handler contains logic for actually executing an action: it accepts a command as a param, handles it in some way, and (if successful) produces an output object.
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;
Example usage:
// 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);
Everything works pretty nice, as you can see in the usage example, but one thing that bothers me is the empty interface ICommand
. Is it a bad thing here? Can the code be refactored in some way to make it better?
c# object-oriented generics interface
Could you add the implementation forCreateUserCommand
? Regarding your question about theICommand
interface: why does it not have this APICommandResult<TResultData> Handle(TCommand command);
? It's more natural to have it there than on a separateICommandHandler
. It'd be also nice if ou could add its implementation too.
â t3chb0t
Feb 23 at 20:29
@t3chb0t, I added command implementation. Command doesn't have Handle method because I want to separate input data from the logic that processes it (to be possible to inject data into handlers using DI, like IRepository in the example, or to have multiple handlers for one command)
â Andre Borges
Feb 23 at 20:50
Multiple handlers for one command? This doesn't sound like a good idea. Your command is more like a command-parameter and the actual command is the handler.
â t3chb0t
Feb 23 at 21:10
Well, I'm not gonna argue for/against multiple handlers (anyway, it's not implemented in my code as you can see) as it's a controversial subject indeed. But there are other reasons for separating data & logic: constructor DI possibility in handlers, avoiding fat classes (there may me dozens of props in commands and several methods in complicated handlers), etc.
â Andre Borges
Feb 23 at 21:35
I'm trying to use something very similar but I get a compilation error on the.Process
call, telling me the compiler cannot infer the type from usage. I have to pass both the command interface and the type of the return value for it to work, which obviously is less than ideal. Any tips? Your code as-is doesn't compile for me.
â julealgon
Jun 15 at 21:58
add a comment |Â
up vote
2
down vote
favorite
up vote
2
down vote
favorite
I'm trying to implement business logic layer based on concepts of commands and command handlers.
A command is a thing that contains input parameters for executing some action, and it knows what kind of output that action should produce. A command handler contains logic for actually executing an action: it accepts a command as a param, handles it in some way, and (if successful) produces an output object.
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;
Example usage:
// 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);
Everything works pretty nice, as you can see in the usage example, but one thing that bothers me is the empty interface ICommand
. Is it a bad thing here? Can the code be refactored in some way to make it better?
c# object-oriented generics interface
I'm trying to implement business logic layer based on concepts of commands and command handlers.
A command is a thing that contains input parameters for executing some action, and it knows what kind of output that action should produce. A command handler contains logic for actually executing an action: it accepts a command as a param, handles it in some way, and (if successful) produces an output object.
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;
Example usage:
// 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);
Everything works pretty nice, as you can see in the usage example, but one thing that bothers me is the empty interface ICommand
. Is it a bad thing here? Can the code be refactored in some way to make it better?
c# object-oriented generics interface
edited Feb 23 at 20:47
asked Feb 23 at 19:27
Andre Borges
1755
1755
Could you add the implementation forCreateUserCommand
? Regarding your question about theICommand
interface: why does it not have this APICommandResult<TResultData> Handle(TCommand command);
? It's more natural to have it there than on a separateICommandHandler
. It'd be also nice if ou could add its implementation too.
â t3chb0t
Feb 23 at 20:29
@t3chb0t, I added command implementation. Command doesn't have Handle method because I want to separate input data from the logic that processes it (to be possible to inject data into handlers using DI, like IRepository in the example, or to have multiple handlers for one command)
â Andre Borges
Feb 23 at 20:50
Multiple handlers for one command? This doesn't sound like a good idea. Your command is more like a command-parameter and the actual command is the handler.
â t3chb0t
Feb 23 at 21:10
Well, I'm not gonna argue for/against multiple handlers (anyway, it's not implemented in my code as you can see) as it's a controversial subject indeed. But there are other reasons for separating data & logic: constructor DI possibility in handlers, avoiding fat classes (there may me dozens of props in commands and several methods in complicated handlers), etc.
â Andre Borges
Feb 23 at 21:35
I'm trying to use something very similar but I get a compilation error on the.Process
call, telling me the compiler cannot infer the type from usage. I have to pass both the command interface and the type of the return value for it to work, which obviously is less than ideal. Any tips? Your code as-is doesn't compile for me.
â julealgon
Jun 15 at 21:58
add a comment |Â
Could you add the implementation forCreateUserCommand
? Regarding your question about theICommand
interface: why does it not have this APICommandResult<TResultData> Handle(TCommand command);
? It's more natural to have it there than on a separateICommandHandler
. It'd be also nice if ou could add its implementation too.
â t3chb0t
Feb 23 at 20:29
@t3chb0t, I added command implementation. Command doesn't have Handle method because I want to separate input data from the logic that processes it (to be possible to inject data into handlers using DI, like IRepository in the example, or to have multiple handlers for one command)
â Andre Borges
Feb 23 at 20:50
Multiple handlers for one command? This doesn't sound like a good idea. Your command is more like a command-parameter and the actual command is the handler.
â t3chb0t
Feb 23 at 21:10
Well, I'm not gonna argue for/against multiple handlers (anyway, it's not implemented in my code as you can see) as it's a controversial subject indeed. But there are other reasons for separating data & logic: constructor DI possibility in handlers, avoiding fat classes (there may me dozens of props in commands and several methods in complicated handlers), etc.
â Andre Borges
Feb 23 at 21:35
I'm trying to use something very similar but I get a compilation error on the.Process
call, telling me the compiler cannot infer the type from usage. I have to pass both the command interface and the type of the return value for it to work, which obviously is less than ideal. Any tips? Your code as-is doesn't compile for me.
â julealgon
Jun 15 at 21:58
Could you add the implementation for
CreateUserCommand
? Regarding your question about the ICommand
interface: why does it not have this API CommandResult<TResultData> Handle(TCommand command);
? It's more natural to have it there than on a separate ICommandHandler
. It'd be also nice if ou could add its implementation too.â t3chb0t
Feb 23 at 20:29
Could you add the implementation for
CreateUserCommand
? Regarding your question about the ICommand
interface: why does it not have this API CommandResult<TResultData> Handle(TCommand command);
? It's more natural to have it there than on a separate ICommandHandler
. It'd be also nice if ou could add its implementation too.â t3chb0t
Feb 23 at 20:29
@t3chb0t, I added command implementation. Command doesn't have Handle method because I want to separate input data from the logic that processes it (to be possible to inject data into handlers using DI, like IRepository in the example, or to have multiple handlers for one command)
â Andre Borges
Feb 23 at 20:50
@t3chb0t, I added command implementation. Command doesn't have Handle method because I want to separate input data from the logic that processes it (to be possible to inject data into handlers using DI, like IRepository in the example, or to have multiple handlers for one command)
â Andre Borges
Feb 23 at 20:50
Multiple handlers for one command? This doesn't sound like a good idea. Your command is more like a command-parameter and the actual command is the handler.
â t3chb0t
Feb 23 at 21:10
Multiple handlers for one command? This doesn't sound like a good idea. Your command is more like a command-parameter and the actual command is the handler.
â t3chb0t
Feb 23 at 21:10
Well, I'm not gonna argue for/against multiple handlers (anyway, it's not implemented in my code as you can see) as it's a controversial subject indeed. But there are other reasons for separating data & logic: constructor DI possibility in handlers, avoiding fat classes (there may me dozens of props in commands and several methods in complicated handlers), etc.
â Andre Borges
Feb 23 at 21:35
Well, I'm not gonna argue for/against multiple handlers (anyway, it's not implemented in my code as you can see) as it's a controversial subject indeed. But there are other reasons for separating data & logic: constructor DI possibility in handlers, avoiding fat classes (there may me dozens of props in commands and several methods in complicated handlers), etc.
â Andre Borges
Feb 23 at 21:35
I'm trying to use something very similar but I get a compilation error on the
.Process
call, telling me the compiler cannot infer the type from usage. I have to pass both the command interface and the type of the return value for it to work, which obviously is less than ideal. Any tips? Your code as-is doesn't compile for me.â julealgon
Jun 15 at 21:58
I'm trying to use something very similar but I get a compilation error on the
.Process
call, telling me the compiler cannot infer the type from usage. I have to pass both the command interface and the type of the return value for it to work, which obviously is less than ideal. Any tips? Your code as-is doesn't compile for me.â julealgon
Jun 15 at 21:58
add a comment |Â
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f188218%2fprocessor-for-handling-generic-commands%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Could you add the implementation for
CreateUserCommand
? Regarding your question about theICommand
interface: why does it not have this APICommandResult<TResultData> Handle(TCommand command);
? It's more natural to have it there than on a separateICommandHandler
. It'd be also nice if ou could add its implementation too.â t3chb0t
Feb 23 at 20:29
@t3chb0t, I added command implementation. Command doesn't have Handle method because I want to separate input data from the logic that processes it (to be possible to inject data into handlers using DI, like IRepository in the example, or to have multiple handlers for one command)
â Andre Borges
Feb 23 at 20:50
Multiple handlers for one command? This doesn't sound like a good idea. Your command is more like a command-parameter and the actual command is the handler.
â t3chb0t
Feb 23 at 21:10
Well, I'm not gonna argue for/against multiple handlers (anyway, it's not implemented in my code as you can see) as it's a controversial subject indeed. But there are other reasons for separating data & logic: constructor DI possibility in handlers, avoiding fat classes (there may me dozens of props in commands and several methods in complicated handlers), etc.
â Andre Borges
Feb 23 at 21:35
I'm trying to use something very similar but I get a compilation error on the
.Process
call, telling me the compiler cannot infer the type from usage. I have to pass both the command interface and the type of the return value for it to work, which obviously is less than ideal. Any tips? Your code as-is doesn't compile for me.â julealgon
Jun 15 at 21:58