Autofac 属性 注入总是空的

Autofac Property Injection is always null

我正在尝试在控制台应用程序中使用 Autofac 注册类型。但是当我调用实现时它总是空的。请指导。我不想通过容器解决它。

这里的问题是 _dbFactory 总是 null

public class DatabaseHelpers
{
    public IDatabaseFactory _dbFactory {get; set;}

    public void Execute(string commandText) 
    {
        var cmd = _dbFactory.CreateCommand();

        cmd.CommandText = commandText;
        cmd.CommandType = CommandType.Text;

        cmd.ExecuteNonQuery();
    }
}

控制台应用代码

static void Main(string[] args)
    {
        Register();

        var a = new DatabaseHelpers();

        a.Execute("test");
    }

    public static void Register()
    {
        var builder = new ContainerBuilder();
        builder.RegisterType<SqlFactory>().As<IDatabaseFactory>().InstancePerLifetimeScope() ;
        var container = builder.Build();
    }
}

我不希望使用容器和从容器调用 DatabaseHelpers 方法来解决它,如下所示。我只想通过创建 DatabaseHelper

的实例来使用客户端中的现有代码
var app = container.Resolve<DatabaseHelper>();
container.Execute();

有什么想法吗?

已通过 SSS 的各种评论提供了部分答案,其中包含许多好的提示。

让我补充一点背景知识。

您可以将依赖注入视为围墙花园:您的 objective,在设计组件时,是用完整的依赖列表声明它们,作为构造函数参数或属性,因此您永远不必在代码中调用 "new"。当然,最初的工厂创建除外。

让我描述一个关于数据库管理的例子。

您可以有许多服务 class,它们需要访问数据库。 需要访问数据库时,它们需要存在 DbConnection(在您的示例中是 DbHelper,但让我向您展示 DbConnection 的情况)。因此,您添加了一个 DbConnection 类型的构造函数参数(或 Func,如果您想要一个委托,您可以多次调用以获得多个连接)。服务不关心 DbConnection 是如何构建的,它们只是声明它们需要一个有效的连接。

public class MyService
{
    private readonly Func<DbConnection> _connectionGetter;
    private DbConnection _connection = null;
    public DbConnection Connection
    {
        get { return _connection ?? (_connection = _connectionGetter()); }
    }

    public MyService(Func<DbConnection> connectionGetter)
    {
        _connectionGetter = connectionGetter;
    }
}

然后您声明 DbConnection 是由您的工厂创建的 class。类似于:

builder.Register<DbConnection>(c => c.Resolve<IDbFactory>().CreateConnection())
    .AsSelf()
    .InstancePerDependency();

然后您以类似的方式注册您的工厂。

通过这种方式,您永远不会调用 new,每个依赖项都由 Autofac 保留,您就可以开始了。只需实例化一个容器构建器,它会依次实例化一个 main class(或者控制器工厂,如果你在 MVC 领域),它将自动配置。

一些提示,按不同顺序排列: - 如果您需要直接在服务中解析类型,您可以采用 ILifetimeScope 类型的依赖项(声明 属性 或构造函数参数)。 - 构造函数参数注入是更可取的,因为参数列表更容易阅读并且你有一个完整的依赖列表,只有一个地方。我会使用 属性 注入的唯一情况是用于基础 class 中的参数,因此派生的 classes 不需要通过构造函数提供父 [=] 的所有依赖项38=].

我希望这可以帮助您了解 DI 的工作原理。

祝你代码顺利!