Having defined a domain model I want to figure out how to do the rest of work.
DATA ACCESS LAYER
I had read before that it is not necessary to code own UnitOfWork implementation over ISession (thogh I found a much information on how to do it pretty well). So I'm quite confused.. I have repository interface like this:
public interface IRepository<T> where T: AbstractEntity<T>, IAggregateRoot
{
T Get(Guid id);
IQueryable<T> Get(Expression<Func<T, Boolean>> predicate);
IQueryable<T> Get();
T Load(Guid id);
void Add(T entity);
void Remove(T entity);
void Remove(Guid id);
void Update(T entity);
void Update(Guid id);
}
Where in the concrete implementation there are two options:
OPTION A
Is to inject ISessionFactory thru constructor and have something similar to:
public class Repository<T> : IRepository<T> where T : AbstractEntity<T>, IAggregateRoot
{
private ISessionFactory sessionFactory;
public Repository(ISessionFactory sessionFactory)
{
this.sessionFactory = sessionFactory;
}
public T Get(Guid id)
{
using(var session = sessionFactory.OpenSession())
{
return session.Get<T>(id);
}
}
}
OPTION B
Is to use NHibernateHelper class
using(var session = NHibernateHelper.GetCurrentSession())
{
return session.Get<T>(id);
}
Where NHibernateHelper is
internal sealed class NHibernateHelper
{
private const string CurrentSessionKey = "nhibernate.current_session";
private static readonly ISessionFactory sessionFactory;
static NHibernateHelper()
{
sessionFactory = new Configuration().Configure().BuildSessionFactory();
}
public static ISession GetCurrentSession()
{
HttpContext context = HttpContext.Current;
ISession currentSession = context.Items[CurrentSessionKey] as ISession;
if(currentSession == null)
{
currentSession = sessionFactory.OpenSession();
context.Items[CurrentSessionKey] = currentSession;
}
return currentSession;
}
public static void CloseSession()
{
HttpContext context = HttpContext.Current;
ISession currentSession = context.Items[CurrentSessionKey] as ISession;
if(currentSession == null)
{
return;
}
currentSession.Close();
context.Items.Remove(CurrentSessionKey);
}
public static void CloseSessionFactory()
{
if(sessionFactory != null)
{
sessionFactory.Close();
}
}
}
What's option is prefered?
Why(besides the injection)?
If I use option A where do I place configuration of ISessionFactory?
Should it be placed somewhere in ASP.NET MVC project? How?
Thank you for reading the monster-question! Your guidance is appreciated!
How to handle injecting dependencies with mvc is somewhat version specific but it always helps to use a real Dependency Injection (DI) container. However you slice it, this solution will need you to Inject an ISession into the Repository rather than an ISessionFactory. This allows your DI container to manage the lifetime of the session properly.
Assuming you're using Asp.Net MVC 3 and dont have an attachment to a specific DI container already, fire up your Nuget console and type:
install-package Ninject.MVC3
This will go, download Ninject (which is a DI container) and configure your mvc application to use it. It will also create a file ~/App_Start/NinjectMVC3.cs which is where you'll configure your dependencies as such.
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<ISessionFactory>()
.ToMethod(c => new Configuration().Configure().BuildSessionFactory())
.InSingletonScope();
kernel.Bind<ISession>()
.ToMethod((ctx) => ctx.Kernel.Get<ISessionFactory>().OpenSession())
.InRequestScope();
kernel.Bind<IRepository<>>().To<Repository<>>();
}
The first statement tells ninject that when something requires an ISessionFactory, it should lazily initialize NHibernate and create one. This session factory is then to be held as an application-wide singleton for the lifetime of the application.
The second statement tells ninject that when something requires an ISession, it should get an instance of ISessionFactory and call OpenSession(). This Session is then reused within the scope of the request and destroyed at the end of the request.
The third statement tells ninject that when something requires an IRepository of any type, it should just new one up using it's built in logic to resolve dependencies.
From here you can write your code as follows and everything should just work.
public class WidgetController : Controller
{
private readonly IRepository<Widget> _repository;
public WidgetController(IRepository<Widget> repository)
{
_repository = repository;
}
}
With regards to the Repository I'd like to point you to an excelent blog post Repository is the new Singleton
I usually use a read only property, on my repository, like this
protected ISession Session
{
get
{
return NHibernateSessionFactory.CurrentFor(dataBaseFactoryKey);
}
}
My NHibernateSessionFactory works like this.
In web apps you should use pattern NH session per web request. I think you should have only one session per web request and your repositories should use this single session.
To implement this you need to write IHttpModule which will open session, begin transaction and bind session as ambient (current) session when request begins and end transaction and close session when request ends. You also need to set current_session_context_class to "web". Then your Repository/DAO will look like this
public TEntity Get(object id)
{
return sessionFactory.GetCurrentSession().Get<TEntity>(id);
}
Best pattern with MVC and NHibernate is session per request.
steps:
In Global.asax add
public static ISessionFactory SessionFactory;
In Application_Start() configure and build session factory:
var config = new Configuration().Configure();
SessionFactory = config.BuildSessionFactory();
In Application_BeginRequest open the session and bind it to
CurrentSessionContext:
var nhSession = SessionFactory.OpenSession();
CurrentSessionContext.Bind(Session);
In Application_EndRequest() unbind and dispose the session
Now in your controller you can access your session invoking:
Global.SessionFactory.GetCurrentSession();
EDIT: Following #hival comment
Inside your controller handle your model in a using block and perform commit/rollback based on your logic.
Related
I have a windows forms application where I am trying to use dependency injection for some services, so I did the following configuration initially in Program.cs I register the services:
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var services = new ServiceCollection();
ConfigureServices(services);
using (ServiceProvider serviceProvider = services.BuildServiceProvider())
{
var mainForm = serviceProvider.GetRequiredService<SelecionarEmpresa>();
Application.Run(mainForm);
}
}
private static void ConfigureServices(ServiceCollection services)
{
services.AddDbContext<AnalistDbContext>();
services.AddSingleton<MainForm>();
services.AddScoped<Form1>();
services.AddScoped<Form2>();
services.AddScoped<Form3>();
services.AddTransient<IEmpRepository, EmpRepository>();
services.AddTransient<ISisRepository, SisRepository>();
}
}
So far everything working, there are 3 Forms I made to test the functionality, in Form1 I inject the services I need:
private readonly ISisRepository _sisRepository;
private readonly IEmpRepository _empRepository;
public Form1(ISisRepository sistRepository,
IEmpRepository empRepository)
{
_sisRepository= sistRepository;
_empRepository = empRepository;
InitializeComponent();
}
And the idea is to use, for example, _sisRepository to update a record, the first time I save it works, if I click to save again, an exception is raised, before putting the exception I already inform you that I am using a generic repository, which is the next:
public abstract class Repository<TEntity> : IRepository<TEntity> where TEntity : Entity, new()
{
protected readonly AnalistDbContext Db;
protected readonly DbSet<TEntity> DbSet;
protected Repository(AnalistDbContext db)
{
Db = db;
DbSet = db.Set<TEntity>();
Db.ChangeTracker.AutoDetectChangesEnabled = false;
var existeBanco = (Db.Database.GetService<IDatabaseCreator>() as RelationalDatabaseCreator).Exists();
if (!existeBanco)
{
(Db.Database.GetService<IDatabaseCreator>() as RelationalDatabaseCreator).Create();
(Db.Database.GetService<IDatabaseCreator>() as RelationalDatabaseCreator).CreateTables();
}
}
public IEnumerable<TEntity> Buscar(Expression<Func<TEntity, bool>> predicate)
{
return DbSet.Where(predicate).AsNoTracking().ToList();
}
public virtual TEntity ObterPorId(Guid id)
{
return DbSet.AsNoTracking().FirstOrDefault(s => s.Id == id);
}
public virtual List<TEntity> ObterTodos()
{
return DbSet.AsNoTracking().ToList();
}
public void Adicionar(TEntity entity)
{
DbSet.Add(entity);
SaveChanges();
}
public void Atualizar(TEntity entity)
{
DbSet.Update(entity);
SaveChanges();
}
public void Remover(Guid id)
{
DbSet.Remove(new TEntity { Id = id });
SaveChanges();
}
public int SaveChanges()
{
return Db.SaveChanges();
}
public void Dispose()
{
Db?.Dispose();
}
}
The exception is:
Despite the clarity of the message, I could not understand if this is a problem caused by the use of dependency injection in the Form's constructor and having caused some problem in relation to the repository instance, it seems that my object is still the same as instantiated earlier, because as I said, this error only occurs on the second call. If that is really the problem, how could you solve it? Or when it comes to windows forms, would I abandon the use of dependency injection?
When you update an item, the DbContext starts tracking that item. When you do a second update, the same DbContext tries to track another item with the same id. It's not an issue with the dependency injection, it's an issue with the lifetime of the injected AnalistDbContext and the objects tracked by it.
Typically, a DbContext would be instantiated on a per-operation basis, instead of living for the duration of the entire form. This helps prevent inconsistencies when two users are trying to modify the same entity. You could try:
Update Form1 to use a factory that can create repositories, and dispose the repository after using it
Update Repository to use a factory that can create an AnalistDbContext, and dispose the context after using it
If you think you're going to be the only user updating the entry, and aren't worried about race conditions or anything like that, you can check if the entry is already being tracked by the db context before trying to attach it.
I've been working on several non-web applications with Entity Framework and always it was struggling for me to find a correct approach for implementing Generic Repository with DbContext.
I've searched a lot, many of articles are about web applications which have short-living contexts. In desktop approaches I can't find suitable method.
One approach is DbContext per ViewModel but I don't agree with coupling View with Repository layers.
Another one is using using clause this way:
using(var context = new AppDbContext())
{
// ...
}
but this way we will not have Unit of Work and also can't use IoC Containers.
So what is the best practice for using DbContext in desktop applications?
A DbContext is meant to be short-lived: it represents a unit-of-work in itself. If you need long-term object state management then you can use the ObjectStateManager in Entity Framework directly.
For ensuring access to a DbContext, add an interface IDbContextFactory<TDbContext> (or just IMyDbContextFactory if you only have a single DbContext type) and inject that into your ViewModels and use a short-lived DbContext from it:
interface IDbContextFactory<TDbContext>
where TDbContext : DbContext
{
TDbContext Create();
}
// Configure:
void ConfigureServices( YourContainer container )
{
container.RegisterSingleton( IDbContextFactory<YourDbContextType1>, // etc );
container.RegisterSingleton( IDbContextFactory<YourDbContextType2>, // etc );
container.RegisterSingleton( IDbContextFactory<YourDbContextType3>, // etc );
}
// Usage:
public class LongLivedViewModel
{
private readonly IDbContextFactory<YourDbContextType3> dbFactory;
public LongLivedViewModel( IDbContextFactory<YourDbContextType3> dbFactory)
{
this.dbFactory = dbFactory ?? throw new ArgumentNullException(nameof(dbFactory));
this.DoSomethingCommand = new RelayCommand( this.DoSomethingAsync )
}
public RelayCommand DoSomethingCommand { get; }
public async RelayCommand DoSomethingAsync()
{
using( YourDbContextType3 db = this.dbFactory.Create() )
{
// do stuff
await db.SaveChangesAsync();
}
}
}
Entity Framework Core has a built in IDbContextFactory interface.
If using SQL Server, for instance, you declare the following in the ConfigureServices method (which in WPF is generally put in App.xaml.cs).
private static void ConfigureServices(IServiceCollection services)
{
services.AddDbContextFactory<MyDbContext>(
options =>
options.UseSqlServer(MyConnectionString));
}
Make sure MyDbContext exposes this constructor:
public class MyDbContext : DbContext
{
public MyDbContext(DbContextOptions<MyDbContext> options)
: base(options)
{
}
}
After that use constructor injection in the class that will be using the context (which could be either in the ViewModel layer or the Model layer, depending on your architecture):
private readonly IDbContextFactory<MyDbContext> _contextFactory;
public ModelClass(IDbContextFactory<MyDbContext> contextFactory)
{
this._contextFactory = contextFactory;
}
public void DatabaseOperationMethod()
{
using (var context = this._contextFactory.CreateDbContext())
{
// Do database stuff
}
}
I recently created a solution and thought I would try out the DryIoC container to handle dependency injection. Now, as with many other DI solutions that I have used, the default scope for object reuse is transient. This however seems to be posing a problem for the implementation of the repository pattern that I am using since DryIoC (and many other solutions) cannot register a binding as transient if the referenced class implements IDisposable. As a result, I have temporarily resorted to registering my repositories with Reuse.Singleton. This is definitely a code smell for me, so I was hoping that someone might have some advice on how to avoid this situation - it might be that I am doing a poor job of creating a repository for example.
Here is the code that I use to create the IoC container:
private static Container ConstructNewContainer()
{
var container = new Container(Rules.Default);
container.Register(Made.Of(() => SettingsFactory.CreateSettings()));
container.Register<IRepository<tblMailMessage>, MailMessageRepository>(Reuse.Singleton);
container.Register<IRepository<ProcessedMailMessages>, ProcessedMailMessageRepository>(Reuse.Singleton);
container.Register<IParser, EmailParser>();
container.Register<IMonitor, DatabaseMonitor>();
return container;
}
...and an example repository implementation:
public interface IRepository<T>
{
void Insert(T objectToInsert);
void Delete(int id);
void Update(T objectToUpdate);
void Save();
T GetById(long id);
IEnumerable<T> Get();
T Last();
bool Exists(int id);
}
public class MailMessageRepository : IRepository<tblMailMessage>, IDisposable
{
private bool _disposed;
private readonly CoreDataModel _model;
public MailMessageRepository()
{
_model = new CoreDataModel();
}
public void Delete(int id)
{
var objectToDelete = _model.tblMailMessages.Find(id);
if (objectToDelete != null) _model.tblMailMessages.Remove(objectToDelete);
}
public void Update(tblMailMessage objectToUpdate) => _model.Entry(objectToUpdate).State = EntityState.Modified;
public void Save() => _model.SaveChanges();
public IEnumerable<tblMailMessage> Get() => _model.tblMailMessages.ToList();
public tblMailMessage Last() => _model.tblMailMessages.OrderByDescending(x => x.DateSubmitted).FirstOrDefault();
public bool Exists(int id) => _model.tblMailMessages.SingleOrDefault(x => x.MailMessageID == id) != null;
public void Insert(tblMailMessage objectToInsert) => _model.tblMailMessages.Add(objectToInsert);
public tblMailMessage GetById(long id) => _model.tblMailMessages.SingleOrDefault(x => x.MailMessageID == id);
#region Dispose
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (!disposing)
{
_model.Dispose();
}
}
_disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
The documentation here explains why disposable transient is the problem and why DryIoc default behavior was selected this way. Basically, the behavior is to inform you about the problem and not just silently go with it.
Regarding other containers, there is no strong preference to particular disposable transients handling. Here is discussion related to Microsoft.Extensions.DependencyInjection with participation of Autofac, StructureMap and other containers developers.
Btw, DryIoc error message contains the tip how to opt-in the problem.
According to the documentation, you have 3 options:
Disallow to register disposable transient service. The default DryIoc behavior.
container.Register<X>(); // will throw exception
Allow to register disposable transient, but delegate the responsibility of disposing the service to container User.
container.Register<X>(setup: Setup.With(allowDisposableTransient: true));
// or allow globally for all container registrations:
var container = new Container(rules => rules.WithoutThrowOnRegisteringDisposableTransient());
container.Register<X>(); // works, but dispose is up to User
To track (store) disposable transient dependency in its owner reuse scope (if any), or to track resolved disposable transient in current Open Scope (if any).
container.Register<X>(setup: Setup.With(trackDisposableTransient: true));
// or track globally for all container registrations:
var container = new Container(rules => rules.WithTrackingDisposableTransients());
// will be tracked in XUser parent in singleton scope and disposed with container as all singletons
container.Register<XUser>(Reuse.Singleton);
container.Register<X>();
// or tracking in open scope
using (var scope = container.OpenScope())
scope.Resolve<X>; // will be disposed on exiting of using block
As you can see above, the default behavior expects you to explicitly dispose when using transient lifestyle.
But they left out the 4th option, which is to find another DI container. I have never used DryIoC, but this seems like too much to worry about that you don't have to with other containers. Normally, choosing the correct lifetime is what determines when to dispose an instance.
I'm writing a sync service between our Salesforce environment and our local environment. My use of the Salesforce API is purely on a batch level due to limitations on # of API requests per day, although I do have details on failures at the atomic level. However, I would like to save changes on a atomic level in my local environment as I don't want an entire transaction to fail if one entity fails.
I am using Entity Framework 6 with a Unit of Work and Repository pattern. Here is my relevant code (Implementation Details Below):
IUnitOfWork
public interface IUnitOfWork: IDisposable
{
IReadUpdateRepository<EntityType1> EntityType1Repository { get; }
ISyncRepository<EntityType2> EntityType2Repository { get; }
ISyncRepository<EntityType3> EntityType3Repository { get; }
...other repos
void SaveChanges();
}
Implementation of IUnitOfWork
public class UnitOfWork : IUnitOfWork
{
private bool _isDisposed;
private DbContext _context;
private ISyncRepository<Entity> _entityRepo;
...other private repos
public UnitOfWork(DbContext context)
{
_context = context;
}
public ISyncRepository<Entity> EntityRepository
{
get
{
if (_entityRepo == null)
_entityRepo = new GenericSyncRepository<Entity>(_context);
return _entityRepo ;
}
}
...other getters for other repos
public void SaveChanges()
{
//client classes handle all errors here
_context.SaveChanges();
}
private void dispose(bool isDisposing)
{
if (!_isDisposed)
{
if (isDisposing)
_context.Dispose();
}
_isDisposed = true;
}
public void Dispose()
{
dispose(true);
}
}
ISyncRepository
public interface ISyncRepository<T> where T : BaseEntity
{
void DeleteItems(IEnumerable<T> items);
void DeleteItemsById(IEnumerable<int> ids);
void DeleteItem(T item);
void InsertItems(IEnumerable<T> items);
void Insert(T item);
T GetItemById(int id);
List<T> GetItems(Expression<Func<T, bool>> predicate = null, Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null, string includeProperties = "");
}
Implementation of ISyncRepository
public class GenericSyncRepository<T> : ISyncRepository<T> where T : BaseEntity
{
private readonly DbContext _context;
private readonly DbSet<T> _set;
public GenericSyncRepository(DbContext context)
{
_context = context;
_set = _context.Set<T>();
}
public T GetItemById(int id)
{
var result = _set.Find(id);
return result;
}
public List<T> GetItems(Expression<Func<T, bool>> predicate = null, Func<IQueryable<T>,IOrderedQueryable<T>> orderBy = null ,string includeProperties = "")
{
IQueryable<T> query = _set.AsExpandable();
if (predicate != null)
{
query = query.Where(predicate);
}
if (!String.IsNullOrEmpty(includeProperties))
{
var splitProps = includeProperties.Split(',');
foreach (var prop in splitProps)
{
query = query.Include(prop);
}
}
if (orderBy != null)
{
return orderBy(query).ToList();
}
return query.ToList();
}
public void DeleteItemsById(IEnumerable<int> ids)
{
var items = ids.Select(i => _set.Find(i));
DeleteItems(items);
}
public void DeleteItem(T item)
{
_set.Remove(item);
}
public void DeleteItems(IEnumerable<T> items)
{
_context.Set<T>().RemoveRange(items);
}
public void Insert(T item)
{
_set.Add(item);
}
public void InsertItems(IEnumerable<T> items)
{
_set.AddRange(items);
}
public List<T> GetViewItems(Expression<Func<T, bool>> predicate)
{
IQueryable<T> query = _set.AsExpandable();
return query.Where(predicate).ToList();
}
}
I am using this repository in services that relate to each object group involved in the sync, into which I inject the IUnitOfWork via the constructor:
private readonly IUnitOfWork _uow;
public EntityDataService(IUnitOfWork uow, ICamsSfDTOMapper mapper)
{
_uow = uow;
}
Then use the UoW to fetch repositories to performs queries:
var repo = _unitOfWork.PartyRepository;
var p = repo.GetItems(p => Ids.Contains(someValue));
And when inserts or updates are made, I can call SaveChanges:
_unitOfWork.SaveChanges();
This works great for data retrieval, however for data persistence, I run into a snag. On the local domain side, I want to iterate through objects one by one, saving changes or inserting and calling SaveChanges to persist. If an error occurs, I store it in a result object that I log at the end of each sync step and continue onto the next object to do work on.
However, as my app is currently structured, if a database exception occurs on SaveChanges, that validation error remains in the context until it is disposed. Since this context is injected into each repository in the UoW class, it sticks around for what I presume is the life of the entire sync process.
I am using Autofac for DI in a WindowsService hosted using TopShelf and I'm registering my UoW as such:
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().WithParameter("context", new EntityModel());
Here are my questions:
Should this question be posted to Code Review :)
I feel like I should invert my repository with UoW, with UoW being passed into each repository and my repositories being passed into each service (a service can make use of more than one repository)
Does it make sense to spin up a new DbContext for each SaveChanges and to have one DbContext (the one passed into UoW) as my read context and all other contexts new'ed up when SavingChanges?
Any help would be appreciated.
Doesn't bother me, I only use SO and don't intend to go anywhere else, and don't mind having questions like these on SO.
I would highly recommend that your service as for IRepository and your repository ask for IUoW. I even like to think of IRepository as more than just a barrier to EF. I normally only use a repository if either
I know for a fact in advance I will be implementing a non EF repository as well otherwise
I want to implement some actual logic which I want abstracted from my service and would not make it generic. E.g. I would make a UserProfileRepository, which would have methods such as SyncCurrentUserProfile rather than exposing Add/Insert/Update. Exposing Add/Insert/Update adds nothing to the equation if I don't plan to use a non EF based model.
It depends. If you don't use tracking, and have a lot of unrelated changes over time. Than yes, as each time you add/update something it will add it to the context, which causes future additions/modifications become slower. But if you are adding/modifying 10 things here and there, probably wouldn't worry about it not unless you need a fresh context each time.
I am actually writing a blog post about this. Will try to post a link later.
So using some assistance from tutorials I have managed to wire up a Nhibernate session to my repositories and my repositories to my controllers using Ninject. However, there is one peice of the setup that I am not grasping the "automagic" of what Ninject is doing and was hoping someone could explain.
Below is my Ninject ModuleRepository that inherits from NinjectModule that does all the binding.
public class ModuleRepository : NinjectModule
{
public override void Load()
{
var helper = new NHibernateHelper(ConfigurationManager.ConnectionStrings[Environment.MachineName].ConnectionString);
Bind<ISessionFactory>().ToConstant(helper.SessionFactory)
.InSingletonScope();
Bind<IUnitOfWork>().To<UnitOfWork>()
.InRequestScope();
Bind<ISession>().ToProvider<SessionProvider>()
.InRequestScope();
Bind<IRepository<Product>>().To<ProductRepository>();
Bind<IRepository<Category>>().To<CategoryRepository>();
}
}
Here is the UnitOfWork class:
public class UnitOfWork : IUnitOfWork
{
private readonly ISessionFactory _sessionFactory;
private readonly ITransaction _transaction;
public ISession Session { get; private set; }
public UnitOfWork(ISessionFactory sessionFactory)
{
_sessionFactory = sessionFactory;
//Open Session
Session = _sessionFactory.OpenSession();
Session.FlushMode = FlushMode.Auto;
_transaction = Session.BeginTransaction(IsolationLevel.ReadCommitted);
}
public void Commit()
{
if (!_transaction.IsActive)
throw new InvalidOperationException("There is no active Transaction");
_transaction.Commit();
}
public void Rollback()
{
if (_transaction.IsActive)
_transaction.Rollback();
}
//Close open session
public void Dispose()
{
Session.Close();
}
}
So I understand that we are creating a single instance constant instance of the object that creates a Nhibernate SessionFactory. Below is the SessionProvider class which returns the session from the UnitOfWork object that wraps each unit of work in a transaction.
SessionProvider
public class SessionProvider : Provider<ISession>
{
protected override ISession CreateInstance(IContext context)
{
var unitOfWork = (UnitOfWork)context.Kernel.Get<IUnitOfWork>();
return unitOfWork.Session;
}
}
The Repositories take a ISession in their constructor. But what I am not seeing is how the UnitOfWork.Session is the "session" that gets passed to my repositories?
Any help in understanding this would be great. Thanks.
The binding using:
Bind<ISession>().ToProvider<SessionProvider>().InRequestScope();
states that it should maintain Request Scope. That means that Ninject will cache all requests for ISession during the entire HttpRequest - so all classes being injected (or explicitly getting an instance) will be using the same instance of the ISession. In your configuration the same goes for the IUnitOfWork.
See this post by Nate Kohari for descriptions of the different scope objects in Ninject.