Well, I'm trying to implement command pattern to create interaction with an object.
Almost all of commands that would be created consist of request to an object and response from that object.
So the question is - how to manage this responses?
It's easy to make, when all commands - void. No matter what they are, you can execute them if they implements #executable# interface, so have
void Execute(object params)
But what to do, when their responses have different types? Maybe the command pattern is not right for this project?
ICommandResponse Execute(object params)
You can return an interface with a ResponseType property that gives you information about the concrete response type.
Make use of .NET's built-in command pattern types and lambdas.
First all all, you do not need your own command patetrn interface. Use Action<T>. So, for example, any command called must be of the following signature:
void Command(object params)
Then, for any command that isn't of this form, provide a lambda shim for it, eg:
() => { SomeCommandThatTakesTwoParamsAndRetrunsInt(parms.part1, params.part2); }
The above lambda then complies with the void Command(object params) requirements.
Command execution result may be event.
Example:
class ChangeNameCommand
{
int _id;
string _name;
IRepository _repository;
IEventPublisher _publisher;
public ChangeNameCommand(int id, string name, IRepository repository, IEventPublisher publisher)
{
_id = id;
_name = name;
_repository = repository;
_publisher = publisher;
}
public void Execute()
{
User user = _repository.Get(_id)
user.Name = _name;
_repository.Save(user);
NameChangedEvent e = new NameChangedEvent();
_publisher.Publish(e);
}
}
class UserNameChanged : IHandler<NameChangedEvent>
{
public void Handle(NameChangedEvent e)
{
//TODO...
}
}
Related
I am using the excellent Simple Injector Ioc framework and would like to "plug in" multiple email output services ie Mandrill, MailChimp etc
My question really is am I doing this correctly as it results in a Cast at my send method.
So I have a simple IEmailOutputService
public interface IEmailOutputService
{
string Identifier { get; }
bool Send(object message, object contents);
}
And a MandrillOutputService (shortened)
public class MandrillOutputService : IEmailOutputService
{
public MandrillOutputService()
{
//DI stuff here
}
public string Identifier => "Mandrill";
public bool Send(EmailMessage message, IEnumerable<TemplateContent> templateContents)
{
if (message == null)
return false;
//send code here
return true;
}
bool IEmailOutputService.Send(object message, object contents)
{
//TODO this doesnt look right!!
var m = message as EmailMessage;
var c = contents as IEnumerable<TemplateContent>;
//forwards method onto bespoke Mandrill Send method above
return Send(m, c);
}
}
I have an EmailContext that gets the Email Output Provider for the logged in User eg "Mandrill" heres the IEmailContext
public interface IEmailContext
{
string GetProvider();
}
EmailOutputComposite is used to select correct Email Output Service
public class EmailOutputComposite : IEmailOutputService
{
private readonly IEmailContext _emailContext;
private readonly IEnumerable<IEmailOutputService> _emailOutputServices;
public string Identifier => "EmailOutputComposite";
public EmailOutputComposite(
IEmailContext emailContext, IEnumerable<IEmailOutputService> emailOutputServices)
{
this._emailContext = emailContext;
this._emailOutputServices = emailOutputServices;
}
bool IEmailOutputService.Send(object message, object contents) =>
this._emailOutputServices
.FirstOrDefault(x => x.Identifier.ToLower() == this._emailContext.GetProvider())
.Send(message, contents);
}
and finally registrations in Simple Injector
container.RegisterCollection(typeof(IEmailOutputService), new[]
{
typeof(MandrillOutputService)
//other emailOutputServices to go here
});
container.Register(typeof(IEmailOutputService), typeof(EmailOutputComposite),
Lifestyle.Singleton);
So my question is am I doing this correctly or is there a better way. I have to get the Users Email Provider (Mandrill) from Database so cant think of another way to do this but was concerned with the Cast I have to do in MandrillOutputService.Send method.
Wouldn't it be simpler to use the Strategy and Factory patterns, forgive me I'm going to change the implementation a bit:
For container registrations:
container.Register<EmailProviderFactory>(Lifestyle.Scoped);
container.Register<MandrillOutputService>(Lifestyle.Scoped);
container.Register<OtherOutputService>(Lifestyle.Scoped);
Then use a factory to resolve my email providers:
public class EmailProviderFactory
{
private readonly Container container;
public EmailProviderFactory(Container container)
{
this.container = container;
}
public IEmailOutputService Create(string provider)
{
switch (provider)
{
case "Mandrill": // should be in a constants class
return container.GetInstance<MandrillOutputService>();
case "Other": // should be in a constants class
return container.GetInstance<OtherOutputService>();
default: throw new ArgumentOutOfRangeException("provider");
}
}
}
I've changed the IEmailOutputService to have one method with explicit types:
public interface IEmailOutputService
{
bool Send(EmailMessage message, IEnumerable<TemplateContent> contents);
}
The email providers :
public class MandrillOutputService : IEmailOutputService
{
public bool Send(EmailMessage message, IEnumerable<TemplateContent> templateContents)
{
// ...
}
}
public class OtherOutputService : IEmailOutputService
{
public bool Send(EmailMessage message, IEnumerable<TemplateContent> templateContents)
{
// ...
}
}
Usage:
foreach(var userEmailProvider in UserEmailProviders) {
// I'm assuming the factory is injected
var emailService = _emailProviderFactory.Create(userEmailProvider.Name);
emailService.Send(new EmailMessage(), new List<TemplateContent>());
}
I do not think you need IEmailContext or a EmailOutputComposite. By using the EmailProviderFactory you will only create a specific provider when you need it.
I see two problems in your design:
You are violating the Liskov Substitution Principle in your MandrillOutputService by accepting only a subset of the accepted types of the IEmailOutputService abstraction; this might cause the appliation to break at runtime when the user supplies values that are invalid for that specific implementation.
The Identifier property on the IEmailOutputService violates the Interface Segration Principle, because it is a method that consumers don't use. The only class that is actually interested in this property is the EmailOutputComposite. Removing the Identifier from the abstraction has the advantage that it can simplify unit testing, since there is less code that a consumer can call. It also simplifies the interface, which is always a good thing.
I'm unsure how to fix the LSP principle, because its unclear to me how other implementations look like.
With respect to the ISP violation, you can do the following to fix it:
Mark the implementations instead with an attribute that defines their Identifier. This allows you to remove the property from the interface, but the downside is that the Composite can only filter those services in case the actual types are injected (and not decorated, because that disallows you from retrieving those attributes).
You let the Composite depend on the actual concrete implementations and implement a switch-case statement inside the Composite. This again allows you to remove the property from the interface, but downside is that you will have to update the composite every time a new implementation is added (which might not be that bad if you consider the Composite part of your Composition Root).
You define a dictionary of IEmailOutputServices during the registration process, where the Identifier is the dictionary's key. This removes the need to have the Identifier as part of the abstraction, but also removes the identifier from the implementation (which might actually be something good).
Here's an example of this last example:
container.RegisterSingleton<IEmailOutputService, EmailOutputComposite>();
container.RegisterSingleton(new Dictionary<string, Func<IEmailOutputService>>()
{
"Mandrill", CreateEmailServiceProducer<MandrillOutputService>(container),
"other", CreateEmailServiceProducer<Other>(container),
// ..
});
privte static Func<IEmailOutputService> CreateEmailServiceProducer<T>(Container c)
where T : IEmailOutputService =>
Lifestyle.Transient.CreateProducer<IEmailOutputService, T>(c).GetInstance;
Where the Composite is implemented as follows:
public class EmailOutputComposite : IEmailOutputService
{
private readonly IEmailContext _emailContext;
private readonly Dictionary<string, Func<IEmailOutputService>> _emailOutputServices;
public EmailOutputComposite(
IEmailContext emailContext,
Dictionary<string, Func<IEmailOutputService>> emailOutputServices)
{
_emailContext = emailContext;
_emailOutputServices = emailOutputServices;
}
public bool Send(object m, object c) => Service.Send(m, c);
IEmailOutputService Service => _emailOutputServices[_emailContext.GetProvider()]();
}
Whether or not this is actually an improvement is up to you.
I've implemented the command pattern (in a multi-support way) in my application.
Structure:
class MultiCommand : BaseCommand
abstract class BaseCommand : ICommand
Process Flow:
var commandsGroup = new MultiCommand(new List<ICommand>()
{
new Command1(),
new Command2(),
new Command3(),
});
commandsGroup.Execute()
Now, suppose that in Command1 a somethingID is changed and I'll use this new value in Command2... And also, that there are plenty of other properties and objects that are being affected during the whole execution process.
Also, there are some interface implementations that should be available at any command just using the context object like:
Context.ServerController.something();
The instantiation of the IServerController will take place just before the multiCommandGroup initialization.
How can I have a shared context like this for all Commands of the group?
Example of the Context class:
public class CommandContext
{
public IServerController ServerController;
public RequiredData Data { get; set; }
public CommandContext(){}
}
IMPORTANT
A minimal implementation Code is here
1) If you want to keep this interface, then you have to pass this context as constructor parameter:
new MultiCommand(new List<ICommand>()
{
new Command1(context),
new Command2(context),
new Command3(context),
})
2) As another option you can accept list of delegates instead of list of commands.
MultiCommand will be look like this:
class MultiCommand : ICommand
{
public MultiCommand(List<Func<Context, Command>> commands, Context context)
}
That is almost the same except MultiCommand is responsible for all the commands share the same context.
3) Looks like commands in MultiCommand depends on result of previous command. In this case Command pattern is not probably the best. Maybe you should try to implement Middleware chain here?
interface IMiddleware<TContext>
{
void Run(TContext context);
}
class Chain<TContext>
{
private List<IMiddleware<TContext>> handlers;
void Register(IMiddleware<TContext> m);
public void Run(TContext context)
{
handlers.ForEach(h => h.Run(context));
}
}
I would suggest to make somethings generic. Here is a super simple example.
class MultiCommand<TContext>
{
List<Command<TContext>> Commands;
TContext Context;
}
You could have a constructor on your BaseCommand class (and its derived classes) that would accept a Context class of some kind. When instantiating the commands that will belong to the same group, you could provide them all the same context object. Maybe something like:
public class CommandContext
{
// The object that will be the target of the commands' actions.
public object Data { get; set; }
// ... any other properties that might be useful as shared state between commands...
}
public abstract class BaseCommand : ICommand
{
protected CommandContext Context { get; private set; }
public BaseCommand(CommandContext ctx)
{
Context = ctx;
}
}
public class ChangeSomethingIDCommand : BaseCommand
{
public ChangeSomethingIDCommand(CommandContext ctx) : base(ctx)
{ }
public void Execute()
{
var target = (SomeDomainClass)Context.Data;
target.SomethingID++;
}
}
// Elsewhere in your code (assuming 'myTargetDomainClassInstance' is
// a SomeDomainClass instance that has been instantiated elsewhere and
// represents the object upon which the commands will do work):
var ctx = new CommandContext { Data = myTargetDomainClassInstance };
var commandGroup = new MultiItemCommand(ctx, new List<ICommand>
{
new ChangeSomethingIDCommand(ctx),
new Command2(ctx),
new Command3(ctx)
});
commandGroup.Execute();
Consider a Functional Style
public class SomeMainClass{
public void MultiCommandInit()
{
MultiCommand.New()
.Add(new Command1())
.Add(new Command2())
.Add(new Command3())
.SharedContext(CC => {
CC.Data = new RequiredData();
CC.ServerController = GetServerController();
});
}
private IServerController GetServerController()
{
// return proper instance of server controller
throw new NotImplementedException();
}
}
Requires this extension method / function...
public static class XMultiCommand
{
// How can I have a shared context like this for all Commands of the group?
public static MultiCommand SharedContext(this MultiCommand mc, Action<CommandContext> CallBack)
{
var cc = new CommandContext();
CallBack(cc);
mc.SharedContext = cc;
return mc;
}
}
Finally, these changes to MultiCommand
public class MultiCommand
{
private System.Collections.Generic.List<ICommand> list;
public List<ICommand> Commands { get { return list; } }
public CommandContext SharedContext { get; set; }
public MultiCommand() { }
public MultiCommand(System.Collections.Generic.List<ICommand> list)
{
this.list = list;
}
public MultiCommand Add(ICommand cc)
{
list.Add(cc);
return this;
}
internal void Execute()
{
throw new NotImplementedException();
}
public static MultiCommand New()
{
return new MultiCommand();
}
}
Cool Things Happen Using Functional Styles
Re-usability soars!
Hyper focus on Single Responsibility concerns
Composition becomes the Norm
Code Maintenance becomes simple
Intellisense becomes your built-in API (just use code commenting)
No radical OOP design patterns are needed
Fluent code becomes very enjoyable to work with
Nested / Decorated Functions are much more easy to imagine and implement
You will never repeat youerself
The Open/Closed principal becomes your religion
Code is now always Clear, Complete and Concise
Some even say no interfaces are needed any longer
In your case, going with injecting context through constructor is fine as mentioned by others. But in general, I would go with injecting the context through method parameters instead:
public class Command1: BaseCommand
{
//inject as parameter instead
public void Execute(Context ctx)
{
}
}
The reasons are:
The context should be managed by CommandGroup so that we have better encapsulation.
The CommandGroup is responsible for executing its list of commands so that it's possible for the CommandGroup to pass to each Command only the parameters each Command really needs, these parameters may be constructed at runtime (maybe by previous Commands) so that it's not possible to pass in these objects as the time we construct the list of commands. Therefore, it's easier to reuse Command and also simplify unit testing these Commands as we don't need to construct the whole context object in unit tests.
Maybe you don't need to care about these things at the moment, but method injection gives more flexibility. If you have worked with some frameworks in .NET, you would see something similar like OwinContext, FilterContext,.. they are passed as parameters and contain relevant information for that context.
In my opinion, your case is not a good fit for Command pattern. A Command represents a user request (action) and these objects could be created dynamically at runtime, but you're predefining your Commands at coding time.
What you're trying to do looks like owin middleware or asp.net web api message handler which are http://www.dofactory.com/net/chain-of-responsibility-design-pattern
And what about changing your approach? I did an architecture for DDD recently and executing a commad implies atomic operation (retrieve aggregate root from persitence, apply domain rules and pesist the aggregate) so I do not in needed of a share context and can batch multiple commands whithout worries.
Here you have an cqrs architecture that use command pattern with the above strategy I posted.
My 0.02:
1) The MultiCommand class looks like a Composite pattern.
You may want to add a GetParentCommand() method at the base command class and add an AddChildCommand() method at the MultiCommand class, which set every children's parent.
Then the children commands could get the context object from its parent. (Context object should also be defined in base class. And it may be of generic type.)
edit:
abstract class BaseCommand<T> : ICommand
{
public T Context { get; set; }
public BaseCommand Parent { get; set; }
}
class MultiCommand : BaseCommand
{
public void AddChildCommand(BaseCommand command)
{
command.parent = this; // we can get parent's context from children now
// put the command in an internal list
}
}
var commandsGroup = new MultiCommand();
commandsGroup.AddChildCommand(new Command1());
commandsGroup.AddChildCommand(new Command2());
commandsGroup.AddChildCommand(new Command3());
commandsGroup.Execute()
2) We may create a global singleton context object. In MultiCommand's Execute function, we could set the current context object before executing children's Execute function. Then child command could just access the singleton context object. And after all children's execution, the MultiCommand could reset the context. (The context is actually a stack here.)
edit:
abstract class BaseCommand : ICommand
{
// it could be put anywhere else as long as it can be accessed in command's Execute
// it can also be a stack
public static CommandContext Context {get; set;}
}
class MutliCommand : BaseCommand
{
public void Execute()
{
// do something to BaseCommand.Context
ChildCommand.Execute();
// do something to BaseCommand.Context
}
}
class ChildComand: BaseCommand
{
void Execute()
{
// do something with BaseCommand.Context
}
}
Another option is to put the context object as a parameter of the Execute function:
class MultiCommand : BaseCommand
{
void Execute(CommandContext context)
{
Children.Execute(context);
}
}
I am a novice/intermediate C# developer trying to accomplish a task I would be comfortable doing in C.
Basically, I'm getting XML requests that I need to respond to with a corresponding response. The request/response pairs are well defined in a structure like:
"Method1Request" receives "Method1Response"
"Method2Request" receives "Method2Response"
...
So, I'm going to create functions in my class called "Method1", "Method2",... that take parameters "Method1Request", "Method2Request",... and return "Method1Response", "Method2Response",...
In code, the function declarations would look like this, and the accompanying code is varied:
Mtehod1Response Method1(Method1Request);
Method2Response Method2(Method2Request);
...
All of the function responses will immediately be serialized into XML, so, theoretically, the functions could all be like this, and could write the result to the private string variable "response":
void Method1(Method1Request)
void Method2(Method2Request)
...
Anyway, what I would like to do is "sample" the XML (already have this working), to find out what type of request it is and use a case statement to, essentially, run the appropriate function on the request and , therefore, generate the correct response.
So, I need to create a function that does all of the steps that remain the same around calling those specific functions. It would basically be structured like this (!PSEUDO CODE!):
void ProcessRequestResponse(Type RequestType, Type ResponseType, Method MethodToRun)
{
...create serializers for RequestType and ResponseType...
...deserialize XML into RequestType...
[ResponseType] [MethodToRun]([RequestType]);
...serialize ResponseType into XML...
...store XML as variable in class...
}
I just have no idea how to actually create that function and have it know what function to run with which types. I looked into using the delegate "Func" methods, but I don't see a way to define them with types that are unknown at the time of creation.
Any direction on how to solve this would be appreciated. I don't think I need to type all of that code for each of my 15+ cases (hopefully!) and manage near identical instances of the almost same code.
I would go the Generics route, implementing some helper class and resolving the request-handling strategy using a configuration object (can be a simple Dictionary).
If you have 15+ request types, I would prefer having 15+ alternative classes, each implementing the corresponding handling strategy.
WARNING: just some throwaway example code, but should give you an head start.
// Define a weakly typed interface, to be called
// by the invoking code.
public interface IRequestHandler
{
public string HandleRequest(string xmlRequest);
}
// Defines a generic handler, accepting two type parameters, one
// for the request, one for the response.
public abstract class RequestHandler<RequestType, ResponseType> : IRequestHandler
{
public XmlSerializer GetRequestSerializer()
{
return GetSerializer(typeof(RequestType));
}
public XmlSerializer GetResponseSerializer()
{
return GetSerializer(typeof(ResponseType));
// an alternative, depending upon your deserialization library,
// could be:
// return GetSerializer<ResponseType>();
}
public XmlSerializer GetSerializer(Type dataType)
{
... resolve based on type.
}
public string HandleRequest(string xmlRequest)
{
if (request == null) throw new ArgumentNullException("request");
var requestSerializer = GetRequestSerializer();
var typedRequest = requestSerializer.Deserialize(xmlRequest) as RequestType;
// response is a ResponseType
var response = ProcessRequest(typedRequest);
var responseSerializer = GetResponseSerializer();
return responseSerializer.Serialize(response);
}
protected abstract ResponseType ProcessRequest(RequestType request);
}
// One handler implementation
// you can just declare the class and RequestHandler inheritance,
// and then right click and ask Visual Studio to "Implement abstract members"
public class ActualRequestHandler : RequestHandler<ActualRequest, ActualResponse>
{
protected ActualResponse ProcessRequest(ActualRequest request)
{
// ... do your processing
}
}
// One handler implementation
public class AnotherRequestHandler : RequestHandler<AnotherRequest, AnotherResponse>
{
protected AnotherResponse ProcessRequest(AnotherRequest request)
{
// ... do your processing
}
}
A simple configuration could be a static dictionary in your external processor class:
private static readonly Dictionary<Type, Func<IRequestHandler>> _strategyGetter = new Dictionary<Type, IRequestHandler>()
{
{typeof(ActualRequest), () => new ActualRequestHandler()},
{typeof(AnotherRequest), () => new AnotherRequestHandler()}
};
And finally, your global code:
Type requestType = ... your existing code processing the string request ...
Func<IRequestHandler> handlerFactoryMethod;
if(_strategyGetters.TryGetValue(requestType, out handlerFactoryMethod))
{
var handler = handlerFactoryMethod();
var responseString = handler(request);
// ... do what you want with responseString ...
}
else
{
// seems the request was not recognized.
}
I think Reflection is a way to solve your problem. Possible example:
Here are your different functions:
class Methodes
{
bool func1(bool a) { ...}
int func2(double b) { ... }
}
First you have to get all MethodInfo (all available methodes) via reflection:
MethodInfo[] AvailableMethodes = typeof(Methodes).GetMethods();
Now you can search the methode you want using a loop through your available methodes. Use the GetParameters() and ReturnType to check if the parameters an types are correct. If you have a match, call a the methode with the Invoke:
foreach (MethodInfo AvailableMethode in AvailableMethodes)
{
if (AvaliableMethode.ReturnType.ToString() == "TheReturnTypeYouWished") //Check your parameters also (use GetParameters)
{
//Call the method if you have a match
AvaliableMethode.Invoke(AInstanceOfMethodes, YourParameter(s));
}
}
C# and most other strongly-typed OO languages implement method overloading. The runtime will automatically dispatch to the correct method of a class based on parameter type, e.g.
ResponseType1 handleRequest(RequestType1 request) { ... }
ResponseType2 handleRequest(RequestType2 request) { ... }
I believe it will work in this case, but can be problematic if there is ambiguity in parameter types (i.e. one method's parameter is a superclass of another's).
Reflection will work but it bypasses compile-time checks and should generally be used only as a last resort.
You can declare a generic class or delegate e.g. RequestHandler<RequestType, ReturnType> and extend it with concrete implementations but the problem of dispatching based on the parameter type is still left as an exercise to the reader.
If design patterns interests you then you can use flavor of Chain of Responsibility(COR) with Command Pattern to redirect the request to it's typed handler.
Design base skeletons -
abstract class RequestBase { }
abstract class ResponseBase { }
/// <summary>
/// Base class which will handle the request if the derived type is responsible otherwise
/// send request to success handler in chain.
/// </summary>
internal abstract class HandlerBase<TRequest, TResponse> // contraints
where TResponse : ResponseBase
where TRequest : RequestBase
{
HandlerBase<TRequest, TResponse> nextHandler;
protected HandlerBase(HandlerBase<TRequest, TResponse> nextHandler)
{
this.nextHandler = nextHandler;
}
public TResponse Execute(TRequest request)
{
if (request == null)
{
throw new ArgumentNullException("request");
}
try
{
if (this.IsResponsible(request))
return this.InternalExecute(request);
else
return this.nextHandler.InternalExecute(request);
}
catch (Exception exception)
{
// log exception and rethrow or convert then throw.
throw;
}
}
protected abstract TResponse InternalExecute(TRequest request);
protected abstract bool IsResponsible(TRequest request);
}
Now realize your concrete requests and their respective handlers e.g.
class RequestA : RequestBase { }
class ResponseA : ResponseBase { }
class RequestB : RequestBase { }
class ResponseB : ResponseBase { }
internal class RequestAHandler : HandlerBase<RequestBase, ResponseBase>
{
public RequestAHandler(HandlerBase<RequestBase, ResponseBase> nextHandler) : base(nextHandler) { }
protected override RequestB InternalExecute(RequestBase request)
{
// do what ever RequestA handler shall do
throw new NotImplementedException();
}
protected override bool IsResponsible(RequestBase request)
{
return request is RequestA;
}
}
internal class RequestBHandler : HandlerBase<RequestBase, ResponseBase>
{
public RequestBHandler(HandlerBase<RequestBase, ResponseBase> nextHandler) : base(nextHandler) { }
protected override RequestB InternalExecute(RequestA request)
{
// do what ever RequestB handler shall do
throw new NotImplementedException();
}
protected override bool IsResponsible(RequestBase request)
{
return request is RequestB;
}
}
Finally putting everything together. We have a COR base class which would invoke the responsible handler to manipulate the request. But we need a dispatcher which knows the chain or handlers and can pass the incoming request.
class Dispatcher
{
// cache chained instances of handlers
private static HandlerBase<RequestBase, ResponseBase> handler = RegisterHandlers();
public static ResponseBase Dispatch(RequestBase request)
{
return handler.Execute(request);
}
private static HandlerBase<RequestBase, ResponseBase> RegisterHandlers()
{
// Build chain
HandlerBase<RequestBase, ResponseBase> contextChain = new RequestAHandler(null);
contextChain = new RequestBHandler(contextChain);
// register new handlers here e.g.
// contextChain = new RequestXHandler(contextChain);
return contextChain;
}
}
Usage -
var response = (ResponseA)Dispatcher.Dispatch(new RequestA());
you might be thinking it's too much of boiler plate code. But that's how the frameworks are built(with boilerplating). Now if you want to add a new Handler of request type of X you just need implement RequestX, ResponseX, RequestXHandler and Register it with dispatcher.
Note- Write unit tests to validate the system. I wrote this code on an online C# editor ;) Cheers!!
I am new to unit testing, so pardon me if I am unable to explain this question properly. I am reading a book "The art of Unit Testing 2nd Edition" and trying to implement unit testing in my project. I am currently stuck or confused when testing using mocking (using NSubstitute as the mocking framework).
Here is my scenario:
I have two interfaces ICommand and IUser
public interface ICommand
{
string execute();
}
public interface IUserCalendar
{
string LoadCalendar();
}
I have a class LoadCalendar which implements ICommand:
public class LoadCalendar : ICommand
{
private IUserCalendar user;
public string execute()
{
return this.user.LoadCalendar();
}
public LoadCalendar(IUserCalendar obj)
{
this.user = obj;
}
}
ViewCalendar implements IUserCalendar:
public class Viewer : IUserCalendar
{
public string LoadCalendar()
{
return "Viewer Load Calendar Called";
}
}
Using an agent class I am invoking command for specific request. (Here I am showing only one request LoadCalendar for one user viewer but I have more command and more users)
My client has an invoker object that invokes the command for specific user.
public class Client
{
public Client()
{ }
public string LoadCalendar(ICommand cmd)
{
Invoker invoker = new Invoker(cmd);
return invoker.execute();
}
}
Now I like to test the client class that when it calls for specific user it should return proper object or message.
[Test]
public void client_Load_Calendar_Administrator()
{
IUserCalendar calanedar = Substitute.For<IUserCalendar>();
ICommand cmd = Substitute.For<ICommand>(calanedar);
Client c = new Client();
c.LoadCalendar(cmd, calanedar).Returns(Arg.Any<string>());
}
I don't know where I am doing wrong and it's throwing an error.
NSubstitute.Exceptions.SubstituteException : Can not provide constructor arguments when substituting for an interface.
Any help is really appreciated. Sorry for long question.
The error you're getting:
Can not provide constructor arguments when substituting for an interface.
Is telling you exactly what's wrong.
You're passing in constructor arguments here:
ICommand cmd = Substitute.For<ICommand>(calanedar);
Of course, interfaces never have a constructor. You're trying to interact with your ICommand interface as if it were your concrete LoadCalendar implementation of it.
Furthermore, to be able to unit test a class you always want to have a default (parameterless) constructor. Many mocking frameworks actually require this.
In this case you should probably test against the concrete class and mock/substitute the classes that it uses.
Either that, or you only substitute ICommand simply to have it return a pre-set (string) value. Then you can proceed to verify if the code that consumes your command, actually invokes it and/or does the correct thing with the value it returns.
To illustrate:
[Test]
public void client_Load_Calendar_Administrator()
{
// You are substituting (mocking) the IUserCalendar here, so to test your command
// use the actual implementation
IUserCalendar calendar = Substitute.For<IUserCalendar>();
ICommand cmd = new LoadCalendar(calendar):
// Let the IUserCalendar.LoadCalendar() return a certain string
// Then Assert/Verify that cmd.Execute() returns that same string
}
That's the point of unit testing: you test the smallest piece of functionality by mocking all dependencies. Otherwise it's an integration test.
To test your client:
[Test]
public void client_Load_Calendar_Administrator()
{
ICommand cmd = Substitute.For<ICommand>();
Client c = new Client();
// Let your command return a certain string
// Then verify that your calendar returns that same string
}
EDIT: In case you're interested, the method in NSubstitute that throws this exception:
private void VerifyNoConstructorArgumentsGivenForInterface(object[] constructorArguments)
{
if (constructorArguments != null && constructorArguments.Length > 0)
{
throw new SubstituteException("Can not provide constructor arguments when substituting for an interface.");
}
}
They're pretty clear about it: no constructor arguments for an interface substitute, no matter what.
I have a CommandHandler that implements some logic for an object and commits context (in my case RavenDb IDocumentSession). I need to implement the same logic for a collection of objects. The first idea is to create a new CommandHandler which would call the first CommandHandler for each object in the foreach. But it would result in N database roundtrips.
The best idea I came to was to create a base CommandHandler with the logic itself but without context commit. Something like this:
internal class AuditProductCommandHandler : AuditProductCommandHandlerBase, ICommandHandler<AuditProductCommand>
{
private readonly IDocumentSession _documentSession;
public AuditProductCommandHandler(IDocumentSession documentSession)
{
_documentSession = documentSession;
}
public void Execute(AuditProductCommand command)
{
AuditProduct(command.Product);
_documentSession.SaveChanges();
}
}
internal class AuditProductsCommandHandler : AuditProductCommandHandlerBase, ICommandHandler<AuditProductsCommand>
{
private readonly IDocumentSession _documentSession;
public AuditProductsCommandHandler(IDocumentSession documentSession)
{
_documentSession = documentSession;
}
public void Execute(AuditProductsCommand command)
{
foreach (var product in command.Products)
{
AuditProduct(product);
}
_documentSession.SaveChanges();
}
}
internal class AuditProductCommandHandlerBase
{
protected void AuditProduct(Product product)
{
//logic itself
}
}
For some reason I feel uncomfortable about this solution. Are there any better options?
I would propose to remove _documentSession.SaveChanges() altogether from the command handler implementation and move the responsibility to the caller. The caller can then decide if they have to chain multiple command handlers or multiple DB operations and then call the SaveChanges() after that. Since caller is responsible for creating/sending the IDocumentSession object, they can take the responsibility of saving and disposing of it too.