I am trying to implement a command pattern with strongly typed input and output parameters for the command itself.
First of all I have created two interfaces that marks the input and the output for the command:
interface IRequest { }
interface IResponse { }
Then I have created the base classes and interfaces. This is the abstract receiver
interface IReceiver<TRequest, TResponse>
where TRequest : IRequest
where TResponse : IResponse
{
TResponse Action( TRequest request );
}
and this the abstract command
abstract class AbstractCommand<TRequest, TResponse>
where TRequest : IRequest
where TResponse : IResponse
{
protected IReceiver<TRequest, TResponse> _receiver;
public AbstractCommand( IReceiver<TRequest, TResponse> receiver ) {
_receiver = receiver;
}
public abstract TResponse Execute( TRequest request );
}
Now I am trying to use these objects and so I have created the needed concrete classes
class TypeARequest : IRequest
{
public TypeARequest() {
}
public int NumericValueA { get; set; }
public int NumericValueB { get; set; }
}
class TypeAResponse : IResponse
{
public TypeAResponse() {
}
public int Result { get; set; }
}
class SumCommand : AbstractCommand<TypeARequest, TypeAResponse>
{
public SumCommand( IReceiver<TypeARequest, TypeAResponse> receiver ) : base( receiver ) {
}
public override TypeAResponse Execute( TypeARequest request ) {
return _receiver.Action( request );
}
}
class SumReceiver : IReceiver<TypeARequest, TypeAResponse>
{
public TypeAResponse Action( TypeARequest request ) {
return new TypeAResponse() { Result = request.NumericValueA + request.NumericValueB };
}
}
Finally I have created a CommandProcessor class which should be able to process multiple commands altogether
class CommandProcessor
{
IList<AbstractCommand<IRequest, IResponse>> _supportedCommands = new List<AbstractCommand<IRequest, IResponse>>();
public CommandProcessor() {
}
void AddSupportedCommand( AbstractCommand<IRequest, IResponse> item ) {
_supportedCommands.Add( item );
}
void SetupSupportedCommands() {
// ERROR HERE
AddSupportedCommand( new SumCommand( new SumReceiver() ) );
}
}
However I am getting a compile time error saying:
Argument 1: cannot convert from 'SumCommand' to 'AbstractCommand'
Any help or suggestion?
You should create an interface and mark your generic parameter as covariance example:
interface IRequest { }
interface IResponse { }
interface IReceiver<in TRequest, out TResponse>
where TRequest : IRequest
where TResponse : IResponse
{
TResponse Action(TRequest request);
}
interface ICommand<out TRequest, out TResponse>
{
}
abstract class AbstractCommand<TRequest, TResponse> : ICommand<TRequest, TResponse>
where TRequest : IRequest
where TResponse : IResponse
{
protected IReceiver<TRequest, TResponse> _receiver;
public AbstractCommand(IReceiver<TRequest, TResponse> receiver)
{
_receiver = receiver;
}
public abstract TResponse Execute(TRequest request);
}
class CommandProcessor
{
IList<ICommand<IRequest, IResponse>> _supportedCommands = new List<ICommand<IRequest, IResponse>>();
public CommandProcessor()
{
}
void AddSupportedCommand(ICommand<IRequest, IResponse> item)
{
_supportedCommands.Add(item);
}
void SetupSupportedCommands()
{
AddSupportedCommand(new SumCommand(new SumReceiver()));
}
}
More information here out modifier msdn
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With