我正在尝试在控制台应用程序中使用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();
任何想法?
答案 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应该如何运作。
祝你好运!