Search code examples
c#nhibernateninjectnhibernate-envers

Nhibernate envers, use dependency injection to add user into revision entity


after reading this and this i come near solution but not to the end since i miss how to apply to my implementation.

i have this custon revision entity and revision listner:

public class _NHRevEntity : DefaultRevisionEntity {
    public virtual int IdUtente { get; set; }
}

public class EnversRevisionListener : IRevisionListener {
    private int _userName = 0;

    public EnversRevisionListener(IUserManagement um) : base() {
        _userName = um.UtenteCorrente.Id;
    }

    public void NewRevision(object revisionEntity) {
        var casted = revisionEntity as _NHRevEntity;
        if (casted != null) {
            casted.IdUtente = _userName;
        }
    }
}

and this is my SessionFactory

public class SessionFactory : IDisposable {
    private static ISessionFactory _sessionFactory;
    private static NHibernate.Cfg.Configuration cfg = new NHibernate.Cfg.Configuration();
    static readonly object factorylock = new object();

    private static void InitializeSessionFactory() {
        _sessionFactory = Fluently.Configure()
                .Database(MsSqlConfiguration.MsSql2008
                .ConnectionString(c => c.FromAppSetting("FluentNHibernateConnection"))
                .ShowSql())
                .Mappings(m => m.FluentMappings.AddFromAssembly(Assembly.GetExecutingAssembly())
                        )
                   .ExposeConfiguration(SetupEnvers)                       
                   .ExposeConfiguration(config => new SchemaUpdate(config).Execute(false, true))
                .BuildSessionFactory();
    }

    private static void SetupEnvers(NHibernate.Cfg.Configuration cfg) {
        var enversConf = new NHibernate.Envers.Configuration.Fluent.FluentConfiguration();
        enversConf.Audit<AutitedClass>();       
        IRevisionListener revListner = new EnversRevisionListener();
        enversConf.SetRevisionEntity<_NHRevEntity>(e => e.Id, e => e.RevisionDate, revListner);
        cfg.IntegrateWithEnvers(enversConf);
    }

    internal ISession OpenSession() {
        lock (factorylock) {
            if (_sessionFactory == null) {
                InitializeSessionFactory();
            }
        }
        NHibernate.ISession session = _sessionFactory.OpenSession();
        return session;
    }       
}

core problem is how to make work injection in revisionListner:

public EnversRevisionListener(IUserManagement um)

EDIT:

going on working i see the real quest: private static void InitializeSessionFactory: since it's static there is no way to inject reference in it. must find different way


Solution

  • solved porting dependency injection into UnitOfWork Class:

    public class UnitOfWork : IUnitOfWork { private static readonly object _syncRoot = new object();

        private ITransaction _transaction;
        private SessionFactory _nhHelper;
        internal ISession _session;
        public UnitOfWork(SessionFactory sf)
        {
            //Contract.Ensures(_session.IsOpen);
            _nhHelper = sf;
            InizializzaSessione();
        }
        public void InizializzaSessione()
        {
            lock (_syncRoot)
            {
                if (_session == null || _session.IsOpen == false)
                {
                    _session = _nhHelper.OpenSession();
                }
            }
        }
    

    and then session factory:

    public class SessionFactory : IDisposable
    {
    
        private static ISessionFactory _sessionFactory;
        private static NHibernate.Cfg.Configuration cfg = new NHibernate.Cfg.Configuration();       
    
        static readonly object factorylock = new object();
        IUserManagement um; 
    
        public SessionFactory(IUserManagement ium)
        {
            um = ium;
        }
    
        private static void InitializeSessionFactory(IUserManagement um, bool genereteDB = false)
        {
            _sessionFactory = Fluently.Configure()
                    .Database(MsSqlConfiguration.MsSql2008
                    .ConnectionString(c => c.FromAppSetting("FluentNHibernateConnection"))
                    .ShowSql())
                    .Mappings(m => m.FluentMappings.AddFromAssembly(Assembly.GetExecutingAssembly())
                                                    .Conventions.AddFromAssemblyOf<SessionFactory>()
                            )
                       .ExposeConfiguration(config => SetupEnvers(config, um))                     
                       .ExposeConfiguration(config => new SchemaUpdate(config).Execute(false, true))
                    .BuildSessionFactory();
        }
    
        private static void SetupEnvers(NHibernate.Cfg.Configuration cfg, IUserManagement um)
        {
            try
            {
                var enversConf = new NHibernate.Envers.Configuration.Fluent.FluentConfiguration();
    
                IRevisionListener revListner = new EnversRevisionListener(um);
                enversConf.SetRevisionEntity<RevisionEntity>(e => e.Id, e => e.RevisionDate, revListner);
             }
            catch (Exception ex)
            {
                throw ex;
            }
    
        }
    
        internal ISession OpenSession()
        {
            lock (factorylock)
            {
                if (_sessionFactory == null)
                {
                    InitializeSessionFactory(um);
                }
            }
            NHibernate.ISession session = _sessionFactory.OpenSession();
    
            return session;
        }
    }