Autofac Property Injection始终为null

时间:2015-11-26 09:08:19

标签: c# dependency-injection console-application autofac

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

此问题是_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();

任何想法?

1 个答案:

答案 0 :(得分:1)

SSS的各种评论已经提供了一个有很多好提示的部分答案。

让我加一点背景。

您可以将依赖注入视为一个带围墙的花园:在设计组件时,您的目标是使用完整的依赖列表声明它们,无论是作为构造函数参数还是属性,因此您永远不必调用&#34; new& #34;在你的代码里面。当然,除了最初的工厂创建。

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

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

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是由您的工厂类生成的。类似的东西:

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

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

通过这种方式,你永远不会打电话给新的,每个依赖都是由Autofac保留的,你很高兴。只需实例化一个容器构建器,它将依次实例化一个主类(或控制器工厂,如果你在MVC中),它将自动配置。

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

我希望这可以帮助您了解DI应该如何运作。

祝你好运!