﻿# Accessing data via NHibernate persistence


NHibernate persistence supports a mechanism that allows using the same data context used by NServiceBus internals to also store business data. This ensures atomicity of changes across the handlers and sagas that process the same message. See [accessing data](/nservicebus/handlers/accessing-data.md) to learn more about other ways of accessing the data in the handlers.


The NServiceBus-managed `ISession` instance can be accessed using the handler context through `context.SynchronizedStorageSession.Session()` or by using [dependency injection](/nservicebus/dependency-injection/index.md).

### Using in a handler

<!-- snippet: NHibernateAccessingDataViaContextHandler -->

```cs
public Task Handle(OrderMessage message, IMessageHandlerContext context)
{
    var nhibernateSession = context.SynchronizedStorageSession.Session();
    nhibernateSession.Save(new Order());
    return Task.CompletedTask;
}
```

<!-- endsnippet -->

<!-- snippet: NHibernateAccessingDataViaDI -->

```cs
[Handler]
public class OrderHandler(INHibernateStorageSession synchronizedStorageSession) :
    IHandleMessages<OrderMessage>
{
    public Task Handle(OrderMessage message, IMessageHandlerContext context)
    {
        synchronizedStorageSession.Session.Save(new Order());
        return Task.CompletedTask;
    }
}
```

<!-- endsnippet -->

> [!NOTE]
> A helper type `INHibernateStorageSession` is used in the example above because by default `ISession` is not registered in the DI container. Users who wish to register `ISession` need to add the following line to the endpoint configuration:

<!-- snippet: AccessingDataConfigureISessionDI -->

```cs
builder.Services.AddScoped<MyRepository, MyRepository>(svc =>
{
    var session = svc.GetService<INHibernateStorageSession>();
    var repository = new MyRepository(session.Session);
    return repository;
});
```

<!-- endsnippet -->

### Using in a saga

> [!WARNING]
> Other than interacting with its own internal state, a saga should not access a database, call out to web services, or access other resources. See [Accessing databases and other resources from a saga](/nservicebus/sagas/index.md#avoid-external-resource-access).

If the situation is special enough to warrant going against this recommendation, the following documentation will describe how to do so.


<!-- snippet: NHibernateAccessingDataViaContextSaga -->

```cs
public class OrderSaga :
    Saga<OrderSaga.SagaData>,
    IHandleMessages<OrderMessage>
{
    public Task Handle(OrderMessage message, IMessageHandlerContext context)
    {
        var nhibernateSession = context.SynchronizedStorageSession.Session();
        nhibernateSession.Save(new Order());
        return Task.CompletedTask;
    }
```

<!-- endsnippet -->


Regardless of how the `ISession` object is accessed, it is fully managed by NServiceBus according to the best practices defined by NServiceBus documentation with regard to transactions.
