5

私は以下を使用します:

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<>));
   }
}

スレッドローカルストレージに関する私の問題は、アプリケーションスレッド全体で同じセッションが使用されることです。これは、第1レベルのキャッシュがクリアされていないことを確認したときに発見しました。私が欲しいのは、IHandleMessages <>。Handleを呼び出す前に、新しいセッションインスタンスを使用することです。構造マップでこれを行うにはどうすればよいですか?メッセージモジュールを作成する必要がありますか?

4

1 に答える 1

3

同じスレッドへのすべてのリクエストに同じセッションが使用されるというのは正しいことです。これは、NSBがリクエストごとに新しいスレッドを作成しないためです。回避策は、カスタムキャッシュモードを追加し、メッセージ処理が完了したときにそれをクリアすることです。

1.スレッドストレージのライフサイクルを延長し、メッセージモジュールに接続します

public class NServiceBusThreadLocalStorageLifestyle : ThreadLocalStorageLifecycle, IMessageModule
{

    public void HandleBeginMessage(){}

    public void HandleEndMessage()
    {
        EjectAll();
    }

    public void HandleError(){}
}

2.構造マップを次のように構成します。

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

お役に立てれば!

于 2010-03-25T08:01:45.380 に答える