首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MediatR和NInject中的单个实例

MediatR和NInject中的单个实例
EN

Stack Overflow用户
提问于 2017-11-09 13:27:23
回答 2查看 1.2K关注 0票数 1

在我的应用程序的引导程序(MVC和NInject)中,我将这两个请求绑定到我的服务上:

代码语言:javascript
复制
  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>();

在服役中,我有

代码语言:javascript
复制
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;
}

但是,由于MediatR在返回消息时创建了MyService的新实例,所以列表是空的:

代码语言:javascript
复制
id=_mediatr.Send(_saveReq); //ok
msgs=mediatr.Send(_getMsgsreq); //always empty

有没有办法强迫MediatR对每个请求使用相同的实例?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-11-09 16:46:42

这是设计出来的--你违背了CQS模式,试图做你想做的事情。命令查询分离。您的处理程序不应该维护状态。

但是,您可以做的是拥有另一个包含该请求的消息列表的具有“每个请求”生存期范围的服务。

这比真正的单例更合适--因为单例将拥有所有消息,用于所有请求(跨用户等)。

首先,在List<string>周围创建一个包装器,其外观如下所示:

代码语言:javascript
复制
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);
    }
}

然后,在NInject中将其配置为InRequestScope

代码语言:javascript
复制
kernel.Bind<IMessageStore>>().To<MessageStore>()
    .InRequestScope();

这将为请求保留MessageStore实例。

在您的处理程序中,接受对IMessageStore的依赖。

代码语言:javascript
复制
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();
    }
}
票数 1
EN

Stack Overflow用户

发布于 2017-11-10 17:10:08

我所做的事情与阿历克斯所提议的类似。我已经创建了一个实现上述句柄功能的HandlerService服务,我将MyService与其作用域注入到httpcontext生命周期中:

kernel.Bind<IMyService>().To<MyService>().InScope(ctx => HttpContext.Current ?? StandardScopeCallbacks.Thread(ctx));

我绑着

代码语言:javascript
复制
 kernel.Bind <IRequestHandler<SaveItemrequest, int>>()
       .To<HandlerService>();
kernel.Bind <IRequestHandler<MyGetmessageRequest, List<string>>>()
       .To<HandlerService>();

现在,我的Handler服务有了对MyService的引用,该引用产生了HttpRequest的生命周期。每个请求都实例化了Handler服务,但是它使用的MyService引用没有实例化,因此消息集合被保留下来,可以在以后进行查询。谢谢。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47203093

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档