2011-07-12 4 views
1

私は、永続エンティティをNHibernateセッションの同じライフタイムスコープに入れたいと思いますか?NHibernate永続エンティティをセッションの同じライフタイムスコープに入れることは可能ですか?

public class ViewModel 
{ 
    readonly Func<Owned<ISession>> _sessionFactory; 

    public ViewModel(Func<Owned<ISession>> sessionFactory) 
    { 
     _sessionFactory = sessionFactory; 
    } 

    public void DoSomething() 
    { 
     using (var session = _sessionFactory()) 
     { 
      using (var trans = session.Value.BeginTransaction()) 
      { 
       session.Value.Get<Model>(1).DoSomething(); 
       trans.Commit(); 
      } 
     } 
    } 
} 

public class Model 
{ 
    readonly ILifetimeScope _lifetimeScope; 

    public Model(ILifetimeScope lifetimeScope) 
    { 
     _lifetimeScope = lifetimeScope; 
    } 

    public void DoSomething() 
    { 
     ISession session = _lifetimeScope.Resolve<ISession>(); 
     Model model = session.Get<Model>(2); 
     model.Text = "test"; 
    } 

    public string Text { get; set; } 
} 

答えて

2

コンストラクタ注入をNHibernateエンティティに行う方法は、IInterceptorを使用することです。からhttp://www.nhforge.org/doc/nh/en/#objectstate-interceptors

インターセプタには、2つの味:ISessionスコープとISessionFactoryスコープがあります。

ISessionスコープのインターセプタは、IInterceptorを受け入れるオーバーロードされたISessionFactory.OpenSession()メソッドの1つを使用してセッションが開かれたときに指定されます。

ISession session = sf.OpenSession(new AuditInterceptor()); 

すでにISessionsを解決するように設定した容器を持っているように見えます。エンティティをインスタンス化できるスコープのあるインターセプタを持つように変更するだけです。

public class AutofacInterceptor : NHibernate.EmptyInterceptor 
{ 
    Autofac.ILifetimeScope scope; 

    public AutofacInterceptor(Autofac.ILifetimeScope scope) 
    { 
     this.scope = scope; 
    } 

    public override object Instantiate(string entityName, EntityMode entityMode, object id) 
    { 
     // use the LifetimeScope to instantiate the correct entity 
    } 
} 

をそしておそらくこのように、あなたのインターセプタでISessionsを解決するためにAutofacを言う:私はこのようなものを想像する

builder.Register(c => 
{ 
    var scope = c.Resolve<ILifetimeScope>(); 
    var factory = c.Resolve<NHibernate.ISessionFactory>(); 
    return factory.OpenSession(new AutofacInterceptor(scope)); 
}) 
.As<NHibernate.ISession>(); 

これはテストされていないですが、私はそれが右のトラックだと思います。 Func<Owned<ISession>>を使用するのではなく、独自のセッションファクトリを定義する必要があります。

あなたの例はあなたのエンティティからISessionにアクセスすることを示しています。私はこれが珍しいと思う。いくつかの人々、like Udiは、エンティティに何かを注入するのが好きではありません。貧血ドメインモデルを避けるためにサービスを注入する必要があるとの意見もあります。しかし、私はエンティティにセッションを注入することは、今まで見たことがありません。

+0

詳細な返信とリンクをありがとう!私は私のプロジェクトでそれを試してみると、私はプロジェクトに大きなリファクタリングをしているので、1〜3日かかるかもしれません。 –

+0

多くの感謝!私はこのアプローチを自分のプロジェクトでテストしました。 –

関連する問題