I am working on a legacy application that uses NInject and nHibernate as part of an ASP.NET MVC (C #) application. I am currently considering a change validation issue. Each object has ChangedOn / ChangedBy and CreatedOn / CreatedBy fields that map to database columns. However, they are either filled in with the wrong username or no username at all. I think this is due to the fact that it was configured incorrectly, but I don't know enough about nHibernate and NInject to solve the problem, so I hope someone can help. Below are some snippets of code that I hope will provide a good idea of ββthe application.
Creating a factory session and session:
public class NHibernateModule : NinjectModule { public override void Load() { Bind<ISessionFactory>().ToProvider(new SessionFactoryProvider()).InSingletonScope(); Bind<ISession>().ToProvider(new SessionProvider()).InRequestScope(); Bind<INHibernateUnitOfWork>().To<NHibernateUnitOfWork>().InRequestScope(); Bind<User>().ToProvider(new UserProvider()).InRequestScope(); Bind<IStamper>().ToProvider(new StamperProvider()).InRequestScope(); } } public class SessionProvider : Provider<ISession> { protected override ISession CreateInstance(IContext context) {
Factory session setup:
public static ISessionFactory CreateSessionFactory(string connectionString, IStamper stamper) { // Info: http://wiki.fluentnhibernate.org/Fluent_configuration return Fluently.Configure() .Database(MsSqlConfiguration.MsSql2008 .ConnectionString(connectionString)) .Mappings(m => { m.FluentMappings .Conventions.Add(PrimaryKey.Name.Is(x => "Id")) .AddFromAssemblyOf<NHibernateHelper>(); m.HbmMappings.AddFromAssemblyOf<NHibernateHelper>(); }) // Register .ExposeConfiguration(c => { c.EventListeners.PreInsertEventListeners = new IPreInsertEventListener[] { new EventListener(stamper) }; c.EventListeners.PreUpdateEventListeners = new IPreUpdateEventListener[] { new EventListener(stamper) }; }) .BuildSessionFactory(); }
Fragment from the list of events:
public bool OnPreInsert(PreInsertEvent e) { _stamper.Insert(e.Entity as IStampedEntity, e.State, e.Persister); return false; }
As you can see, the factory session is in one area. Therefore, eventlistener and stamper also get an instance in this area (I think). And this means that when the user has not logged in yet, the user name in the template is set to an empty string or "Unknown." I tried to compensate for this problem by modifying Stamper. It checks if the username is empty or empty. If this is true, he tries to find the active user and fill in the username with this username:
private string GetUserName() { if (string.IsNullOrWhiteSpace(_userName)) { var user = ServiceLocator.Resolve<User>(); if (user != null) { _userName = user.UserName; } } return _userName; }
But this leads to a completely different username, which also enters the application, registering in the database. I assume this is because it allows the wrong active user, which is the last user to log in, instead of the user who started the transaction.