You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在NHibernate 5.x集成Autofac 4.x时为实体注入依赖?

解决NHibernate懒加载代理下Autofac依赖注入失效的问题

这个问题我之前也碰到过——NHibernate懒加载生成代理时,实体的构造函数依赖没被Autofac注入,非懒加载反而正常。核心原因是NHibernate默认用无参构造函数创建代理实例,且没让Autofac参与代理的依赖注入流程,下面是具体的解决步骤:

1. 修正AutofacBytecodeProvider的注册方式

AutofacBytecodeProvider需要依赖ILifetimeScope来解析容器中的服务,直接用RegisterType是不对的,要改成通过lambda注入容器实例:

using Autofac;
using Autofac.Extras.NHibernate;
using NHibernate.Cfg;

var builder = new ContainerBuilder();

// 注册你的领域服务
builder.RegisterType<PasswordHasher>().As<IPasswordHasher>().InstancePerDependency();

// 注册实体
builder.RegisterType<UserAccount>().AsSelf();

// 关键:正确注册AutofacBytecodeProvider,传入容器的生命周期作用域
builder.Register(c => new AutofacBytecodeProvider(c.Resolve<ILifetimeScope>()))
       .As<IBytecodeProvider>()
       .SingleInstance();

var container = builder.Build();

2. 让NHibernate明确使用Autofac字节码提供者

不要直接设置静态的Environment.BytecodeProvider,而是在NHibernate配置中通过属性指定,确保配置加载时就生效:

var nhConfig = new Configuration();

// 告诉NHibernate使用Autofac的字节码提供者
nhConfig.SetProperty(Environment.BytecodeProvider, "autofac");

// 加载你的映射和其他NHibernate配置
nhConfig.Configure(); // 如果用XML配置文件,确保文件里也设置了bytecode.provider="autofac"
ConfigNHibernateAndAddMappings(nhConfig);

var sessionFactory = nhConfig.BuildSessionFactory();

3. 配置NHibernate使用实体的带参构造函数

这是最关键的一步——默认情况下NHibernate会用无参构造函数实例化实体(包括代理),导致依赖无法注入。你需要在映射中指定使用带IPasswordHasher参数的构造函数:

如果用Fluent NHibernate映射

using FluentNHibernate.Mapping;

public class UserAccountMap : ClassMap<UserAccount>
{
    public UserAccountMap()
    {
        Id(x => x.Id);
        Map(x => x.EMail);
        Map(x => x.HashedPassword);
        
        // 指定使用带IPasswordHasher参数的构造函数
        ConstructorSelector<IPasswordHasher>();
    }
}

如果用XML映射

<class name="YourNamespace.UserAccount">
    <id name="Id" type="Guid">
        <generator class="guid.comb"/>
    </id>
    <property name="EMail"/>
    <property name="HashedPassword"/>
    
    <!-- 配置构造函数注入 -->
    <constructor>
        <param name="passwordHasher" type="YourNamespace.IPasswordHasher"/>
    </constructor>
</class>

4. 移除多余的代理工厂注册

之前你手动注册的StaticProxyFactoryFactory和DefaultCollectionTypeFactory是多余的,AutofacBytecodeProvider会自动处理这些组件,删掉它们避免冲突:

// 删掉这两行!
// builder.RegisterType<StaticProxyFactoryFactory>().As<IProxyFactoryFactory>();
// builder.RegisterType<DefaultCollectionTypeFactory>().As<ICollectionTypeFactory>();

为什么这样能解决问题?

  • 修正后的AutofacBytecodeProvider持有了容器的作用域,能在NHibernate创建实体/代理时从容器中解析依赖;
  • 配置NHibernate使用带参构造函数后,无论是直接加载实体还是生成懒加载代理,NHibernate都会调用带IPasswordHasher的构造函数,Autofac会自动注入所需的依赖;
  • 去掉多余的代理工厂注册,确保Autofac完全接管了字节码和代理的创建流程。

现在你再测试懒加载的场景,UserAccount中的_passwordHasher应该就能正常注入了。

内容的提问来源于stack exchange,提问作者Masoud Sedghi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:07:47