In the bootstrap of my app (MVC with NInject) I bind these two requests to my service:
kernel.Bind <IRequestHandler<SaveItemrequest, int>>()
.To<MyService>();
kernel.Bind <IRequestHandler<MyGetmessageRequest, List<string>>>()
.To<MyService>();
kernel.Bind<SingleInstanceFactory>().ToMethod(ctx => t => ctx.Kernel.TryGet(t));
kernel.Bind<MultiInstanceFactory>().ToMethod(ctx => t => ctx.Kernel.GetAll(t));
kernel.Bind<IMediator>().To<Mediator>();
in the service, I have
public int Handle(SaveItemrequest req){
int id= _db.save(req.Item);
this.messages.add("OK");
return id;
}
public List<string> Handle(MyGetmessageRequest req){
return this.messages;
}
but since MediatR creates a new instance of MyService
when I get back my messages the list is empty:
id=_mediatr.Send(_saveReq); //ok
msgs=mediatr.Send(_getMsgsreq); //always empty
Is there any way to force MediatR to use the same instance for every request?
That's by design - you're going against the CQS pattern trying to do what you're suggesting. Command Query Separation. Your handler shouldn't maintain state.
However, what you could do, is have another service, with 'per request' lifetime scope, that contains the list of messages for that request.
This is more appropriate than a true singleton - as a singleton will have ALL messages, for ALL requests (across users etc...)
Firstly, create a wrapper around a List<string>
that could look like this:
public interface IMessageStore
{
IEnumerable<string> GetMessages();
void AddMessage(string message);
}
public class MessageStore : IMessageStore
{
private List<string> _messages = new List<string>();
public IEnumerable<string> GetMessages()
{
return _messages.ToList();
}
public void AddMessage(string message)
{
_messages.Add(message);
}
}
Then, configure this in NInject to be InRequestScope
kernel.Bind<IMessageStore>>().To<MessageStore>()
.InRequestScope();
This will keep the instance of MessageStore
around for the request.
In your handler, take a dependency on IMessageStore
public class MyService : <IRequestHandler<SaveItemrequest, int>, IRequestHandler<MyGetmessageRequest, List<string>>
{
public MyService(IMessageStore messageStore)
{
_messageStore = messageStore;
}
public int Handle(SaveItemrequest req)
{
int id= _db.save(req.Item);
_messageStore.AddMessage("OK");
return id;
}
public List<string> Handle(MyGetmessageRequest req){
return _messageStore.GetMessages();
}
}