【问题标题】:How to inject dependencies into entities usign NHibernate 5.x integrated with Autofac 4.x?如何使用与 Autofac 4.x 集成的 NHibernate 5.x 将依赖项注入实体?
【发布时间】:2019-12-30 12:39:48
【问题描述】:

正如标题所说,我正在尝试使用与Autofac 4.9.4 集成的NHibernate 5.2.6 将一些依赖项(例如域服务)注入到实体中。 假设我们要将IPasswordHasher域服务注入UserAccount实体:

示例

public class UserAccount 
{
    public virtual Guid Id { get; set; }
    public virtual string EMail { get; set; }
    public virtual string HashedPassword { get; set; }

    private readonly IPasswordHasher _passwordHasher { get; set; }

    protected UserAccount() { }
    public UserAccount(IPasswordHasher passwordHasher)
    {
        _passwordHasher = passwordHasher;
    }

    public virtual void SetCredentials(
      string email, string plainTextPassword)
    {
        EMail = email;
        SetPassword(plainTextPassword);
    }

    public virtual void SetPassword(string plainTextPassword)
    {
        HashedPassword = _passwordHasher.HashPassword(
          EMail, plainTextPassword);
    }
}

我已经阅读了this article,但不幸的是,这篇文章对我来说非常过时且含糊不清。 在我最后一次尝试中,我尝试使用Autofac.Extras.NHibernate NuGet 包设置NHibernate.Cfg.Environment.BytecodeProvide,如下所示:

使用 Autofac.Extras.NHibernate

ContainerBuilder builder = new ContainerBuilder();

//Bootstrap the Autofac container
builder.RegisterType<PasswordHasher>().As<IPasswordHasher>();
builder.RegisterType<UserAccount>().AsSelf();
builder.RegisterType<StaticProxyFactoryFactory>().As<IProxyFactoryFactory>();
builder.RegisterType<DefaultCollectionTypeFactory>().As<ICollectionTypeFactory>();
builder.RegisterType<AutofacBytecodeProvider>().As<IBytecodeProvider>();
var container = builder.Build();

//Assign the BytecodeProvider to NHibernate
NHibernate.Cfg.Environment.BytecodeProvider = container.Resolve<IBytecodeProvider>();

Configuration nhConfig = new Configuration().Configure();
ConfigNHibernateAndAddMappings(nhConfig );

var SessionFactory = nhConfig.BuildSessionFactory();
var session = SessionFactory.OpenSession();

//entity._passwordHasher dependency is null when NHibernta warpped it with proxy
var entity= session.Query<UserAccount>().Where(x => x.EMail == "m@d.com").FirstOrDefault();

问题 当没有延迟加载时,NHibernate 不会使用代理扭曲查询的实体,因此在这种情况下,依赖项将被成功注入。但是当 NHibernate 使用代理扭曲实体时,依赖项不会被注入并保持未初始化,有什么建议吗?

【问题讨论】:

  • 我建议你把数据和行为分开。将需要哈希的代码放在不同的“服务”或“功能”或其他任何地方。
  • @YacoubMassad tnx 为您提供建议,但我们需要向实体注入行为。

标签: c# nhibernate domain-driven-design autofac


【解决方案1】:

您不应将依赖项注入聚合根。

可以使用double dispatch,但现在我更倾向于将值从应用程序/集成传递给域对象(关注)。

代替:

public virtual void SetCredentials(
  string email, string plainTextPassword)
{
    EMail = email;
    SetPassword(plainTextPassword);
}

public virtual void SetPassword(string plainTextPassword)
{
    HashedPassword = _passwordHasher.HashPassword(
      EMail, plainTextPassword);
}

我会选择:

public virtual void SetCredentials(
  string email, byte[] passwordHash)
{
    EMail = email;
    Password = passwordHash;
}

将它作为构造函数会更好。

您的应用程序服务将使用传统的依赖注入来注入哈希实现,并且您的数据访问实现不需要关注依赖关系。

这符合@Yacoub Massad 的建议。它会让你的生活比双重调度更简单。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-13
    • 1970-01-01
    • 2011-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-10
    • 2020-02-21
    相关资源
    最近更新 更多