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 的工作原理。
祝你代码顺利!
我正在尝试在控制台应用程序中使用 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 的工作原理。
祝你代码顺利!