开发者

How can I inject multiple repositories in a NServicebus message handler?

I use the following:

public interface IRepository<T>
{
   void Add(T entity);
}

public class Repository<T>
{
  private readonly ISession session;

  public Repository(ISession session)
  {
    this.session = session;
  }

  public void Add(T entity)
  {
     session.Save(entity);
  }
}

public class SomeHandler : IHandleMessages<SomeMessage>
{
  private readonly IRepository<EntityA> aRepository;
  private readonly IRepository<EntityB> bRepository;

  public SomeHandler(IRepository<EntityA> aRepository, IRepository<EntityB> bRepository)
  {
    this.aRepository = aRepository;
    this.开发者_如何学运维bRepository = bRepository; 
  }

  public void Handle(SomeMessage message)
  {
   aRepository.Add(new A(message.Property);
   bRepository.Add(new B(message.Property);
  }
}

public class MessageEndPoint : IConfigureThisEndpoint, AsA_Server, IWantCustomInitialization
{
   public void Init()
   {
      ObjectFactory.Configure(config =>
        {
            config.For<ISession>()
                .CacheBy(InstanceScope.ThreadLocal)
                .TheDefault.Is.ConstructedBy(ctx => ctx.GetInstance<ISessionFactory>().OpenSession());
            config.ForRequestedType(typeof(IRepository<>))
                .TheDefaultIsConcreteType(typeof(Repository<>));
   }
}

My problem with the threadlocal storage is, is that the same session is used during the whole application thread. I discovered this when I saw the first level cache wasn't cleared. What I want is using a new session instance, before each call to IHandleMessages<>.Handle. How can I do this with structuremap? Do I have to create a message module?


You're right in that the same session is used for all requests to the same thread. This is because NSB doesn't create new threads for each request. The workaround is to add a custom cache mode and have it cleared when message handling is complete.

1.Extend the thread storage lifecycle and hook it up a a message module

public class NServiceBusThreadLocalStorageLifestyle : ThreadLocalStorageLifecycle, IMessageModule
{

    public void HandleBeginMessage(){}

    public void HandleEndMessage()
    {
        EjectAll();
    }

    public void HandleError(){}
}

2.Configure your structuremap as follows:

For<<ISession>>
.LifecycleIs(new NServiceBusThreadLocalStorageLifestyle())
...

Hope this helps!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜