2016-06-22 12 views
1

Ich benutze FluentNHibernate und Unity in meinem asp.net Webapi verwenden. Ich benutze Einheit der Arbeit Muster, um die ISession zu konfigurieren.NHibernate Sitzung wird geschlossen, obwohl der registrierte Typ Unity pro Anfrage verwendet

Ich bekomme Fehler als "Session is closed! Object name: 'ISession'. Kann jemand helfen, was mache ich hier falsch? Hier finden Sie meinen Code.

unityconfig:

container.RegisterType<IUnitOfWork, UnitOfWork>(new ContainerControlledLifetimeManager()); 

public class UnitOfWork : IUnitOfWork 
{ 
    private static readonly ISessionFactory _sessionFactory; 
    private ITransaction _transaction; 

    public ISession Session { get; set; } 

    static UnitOfWork() 
    { 
     _sessionFactory = Fluently.Configure() 
      .Database(MsSqlConfiguration.MsSql2008.ConnectionString(x => x.FromConnectionStringWithKey("UnitOfWorkExample"))) 
      .Mappings(x => x.AutoMappings.Add(
       AutoMap.AssemblyOf<Product>(new AutomappingConfiguration()).UseOverridesFromAssemblyOf<ProductOverrides>())) 
      .ExposeConfiguration(config => new SchemaUpdate(config).Execute(false, true)) 
      .BuildSessionFactory(); 
    } 

    public UnitOfWork() 
    { 
     Session = _sessionFactory.OpenSession(); 
    } 

    public void BeginTransaction() 
    { 
     _transaction = Session.BeginTransaction(); 
    } 

    public void Commit() 
    { 
     try 
     { 
      if (_transaction != null && _transaction.IsActive) 
       _transaction.Commit(); 
     } 
     catch 
     { 
      if (_transaction != null && _transaction.IsActive) 
       _transaction.Rollback(); 

      throw; 
     } 
     finally 
     { 
      Session.Dispose(); 
     } 
    } 

    public void Rollback() 
    { 
     try 
     { 
      if (_transaction != null && _transaction.IsActive) 
       _transaction.Rollback(); 
     } 
     finally 
     { 
      Session.Dispose(); 
     } 
    } 
} 

WebAPI Aktion Filter:

public class UnitOfWorkActionFilter : ActionFilterAttribute 
{ 
    public IUnitOfWork UnitOfWork { get; set; } 

    public override void OnActionExecuting(HttpActionContext actionContext) 
    { 
     UnitOfWork = actionContext.Request.GetDependencyScope().GetService(typeof(IUnitOfWork)) as IUnitOfWork; 
     UnitOfWork.BeginTransaction(); 
    } 

    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) 
    { 
     UnitOfWork = actionExecutedContext.Request.GetDependencyScope().GetService(typeof(IUnitOfWork)) as IUnitOfWork; 
     if (actionExecutedContext.Exception == null) 
     { 
      // commit if no exceptions 
      UnitOfWork.Commit(); 
     } 
     else 
     { 
      // rollback if exception 
      UnitOfWork.Rollback(); 
     } 
    } 
} 
+0

wo Sie die Ausnahme zu bekommen? ist es auf 'UnitOfWork.Commit();' –

+0

in der Zeile _transaction = Session.BeginTransaction(); –

+0

Wenn ich eine Anfrage an Webapi zum ersten Mal mache, funktioniert es, aber das zweite Mal, wenn ich eine Anfrage mache, ruft es nicht den Konstruktor auf. Ich denke, es ist etwas zu tun hier? –

Antwort

1

Verwenden PerRequestLifetimeManager statt ContainerControlledLifetimeManager und sehen. ContainerControlledLifetimeManager registriert ein vorhandenes Objekt als eine Singleton-Instanz, die nicht Ihren Vorstellungen entspricht.

sehen diese für weitere Informationen MSDN

+0

, wenn ich diesen Container verwenden möchte.RegisterType (neuer PerRequestLifetimeManager()); Ich bekomme Typ oder Namespace nicht gefunden für PerRequestLifetimeManager –

+0

Ist das TransientLifeTimeManager? –

+0

Als ich TransientLifeTimeManager verwendet habe, hat es funktioniert. Danke –