将服务注入 Nhibernare Envers 以自定义修订实体

时间:2021-01-14 11:06:08

标签: c# .net-core dependency-injection nhibernate nhibernate-envers

我在 .net 5 Web 应用程序中使用 NHibernate 和 envers,我需要将用户 ID 添加到默认修订实体,但找不到使用依赖注入来做到这一点的方法。

这是envers配置

private static void SetupEnvers(NHibernate.Cfg.Configuration cfg)
    {
        var enversConf = new NHibernate.Envers.Configuration.Fluent.FluentConfiguration();
        enversConf.Audit<Persona>();

        IRevisionListener revListner = new EnversRevisionListener(new IUserManagement);
        enversConf.SetRevisionEntity<RevisionEntity>(e => e.Id, e => e.RevisionDate, revListner);
        cfg.SetEnversProperty(ConfigurationKey.AuditTableSuffix, "_LOG");
        cfg.SetEnversProperty(ConfigurationKey.AuditStrategy, typeof(CustomValidityAuditStrategy));

        cfg.IntegrateWithEnvers(enversConf);
    }

问题是 IRevisionListener revListner = new EnversRevisionListener(new IUserManagement); 我如何注入 UserManagement?

我找到了这个主题 https://nhibernate.jira.com/browse/NHE-17 但我该如何使用它?

这是我的自定义修订实体:

public class RevisionEntity : DefaultRevisionEntity
{
    public virtual string IdUtente { get; set; }
    public virtual string? IdUtenteImpersonato { get; set; }
}

public class EnversRevisionListener : IRevisionListener
{
    IUserManagement um = null;
    public EnversRevisionListener(IUserManagement ium) : base()
    { um = ium; }

    public void NewRevision(object revisionEntity)
    {
        var casted = revisionEntity as RevisionEntity;

        if (casted != null)
        {
            casted.IdUtente = um.GetUtenteCorrente().Id;
            casted.IdUtenteImpersonato = um.GetUtenteCorrente().UtenteImpersonato.Id;
        }
    }
}

这是 nhibernate 配置

    public static IServiceCollection AddNHibernate(this IServiceCollection services, bool genereteDB =         false)
    {   
            _sessionFactory = Fluently.Configure()
                   .Database(OracleManagedDataClientConfiguration.Oracle10
                   .ConnectionString(DbSettings.Current.ConnectionStrings.AbilioDB)
                   .DoNot.ShowSql()
                   .DoNot.FormatSql())
                   .Mappings(m => m.FluentMappings.AddFromAssembly(Assembly.GetExecutingAssembly())
                                                .Conventions.AddFromAssemblyOf<UnitOfWork>()
                        )
                       .ExposeConfiguration(config => SetupEnvers(config))
                       .ExposeConfiguration(config => new SchemaUpdate(config).Execute(false, true))
                .BuildSessionFactory();
        
        services.AddSingleton(_sessionFactory);
        services.AddScoped(factory => _sessionFactory.OpenSession());
        services.AddScoped<IUnitOfWorkFactory, UnitOfWorkFactory>();
        services.AddScoped<IUnitOfWork, UnitOfWork>();

        return services;
    }

1 个答案:

答案 0 :(得分:3)

在容器中注册会话工厂时,将其移动到委托工厂中。该委托工厂提供对可用于解析所需服务的服务提供者的访问

当前的设置代码与实现细节的耦合过于紧密。通过在配置服务时使用延迟工厂委托,可以更轻松地解决依赖关系。

这个

//...

services.AddSingleton(_sessionFactory);
services.AddScoped(factory => _sessionFactory.OpenSession());

//...

需要改成

public static IServiceCollection AddNHibernate(this IServiceCollection services, bool genereteDB = false) {

    services.AddSingleton<ISessionFactory>(sp => Fluently.Configure()
        .Database(OracleManagedDataClientConfiguration.Oracle10
            .ConnectionString(DbSettings.Current.ConnectionStrings.AbilioDB)
            .DoNot.ShowSql()
            .DoNot.FormatSql())
        .Mappings(m => 
            m.FluentMappings.AddFromAssembly(Assembly.GetExecutingAssembly())
                .Conventions.AddFromAssemblyOf<UnitOfWork>()
        )
        .ExposeConfiguration(config => SetupEnvers(config, sp)) //<-- NOTE THIS
        .ExposeConfiguration(config => new SchemaUpdate(config).Execute(false, true))
        .BuildSessionFactory()
    );
    services.AddScoped<ISession>(sp => sp.GetService<ISessionFactory>().OpenSession());
    services.AddTransient<IRevisionListener, EnversRevisionListener>();
    services.AddTransient<IUserManagement, UserManagement>();

    services.AddScoped<IUnitOfWorkFactory, UnitOfWorkFactory>();
    services.AddScoped<IUnitOfWork, UnitOfWork>();

    return services;
}

其中 SetupEnvers 被重构以解决所需的服务

private static void SetupEnvers(NHibernate.Cfg.Configuration cfg, IServiceProvider services) {
    var enversConf = new NHibernate.Envers.Configuration.Fluent.FluentConfiguration();
    enversConf.Audit<Persona>();

    IRevisionListener revListner = services.GetService<IRevisionListener>();
    enversConf.SetRevisionEntity<RevisionEntity>(e => e.Id, e => e.RevisionDate, revListner);
    cfg.SetEnversProperty(ConfigurationKey.AuditTableSuffix, "_LOG");
    cfg.SetEnversProperty(ConfigurationKey.AuditStrategy, typeof(CustomValidityAuditStrategy));

    cfg.IntegrateWithEnvers(enversConf);
}
相关问题