如何使用Func作为一个注入属性

本文关键字:一个 属性 注入 Func 何使用 | 更新日期: 2023-09-27 18:04:53

我试图将Func传递给类实例的公共属性。当我试图访问该属性时,它显示为null。

AutoFac配置:

builder.RegisterType<Func<BillingStore>>().PropertiesAutowired();

公共财产:

public static Func<BillingStore> BillingStoreFactory { get; set; }

我不知道我做错了什么,我通常试图避免委托,但这次我不能。

如何使用Func<T>作为一个注入属性

定义不使用静态关键字

的属性
public Func<BillingStore> BillingStoreFactory { get; set; }

看来这里有很多事情可能会给你带来麻烦。

首先,让我们完成代码示例,这样我们就有东西可以讨论了。我假设您有以下内容:

void Main()
{
    var builder = new ContainerBuilder();
    builder.RegisterType<Func<BillingStore>>().PropertiesAutowired();
    builder.RegisterType<Consumer>();
    var container = builder.Build();
    var consumer = container.Resolve<Consumer>();
    // The BillingStoreFactory property is null here
    // but you want it populated.
}
public class BillingStore { }
public class Consumer
{
  public static Func<BillingStore> BillingStoreFactory { get; set; }
}

问题1:使用静态属性。使其成为实例属性。像Autofac这样的IoC容器处理实例参数和属性,而不是静态的。你的BillingStoreFactory属性需要是一个实例属性。

public class Consumer
{
  public Func<BillingStore> BillingStoreFactory { get; set; }
}

问题2:您将PropertiesAutowired设置在错误的对象上。把它设置在消费者身上。 PropertiesAutowired的意义在于,"当我解析这个对象时,我希望你也注入它的属性。"现在你在函数/工厂上有这个,所以Autofac将尝试在 Func<BillingStore>上注入属性,而不是类型为 Func<BillingStore>的属性。你想用属性——消费对象来填充属性

builder.RegisterType<Consumer>().PropertiesAutowired();

问题3:函数注册不工作如果你做一个RegisterType<T>调用,这意味着Autofac将能够自动计算出T的参数——要么它不接受任何构造函数参数,要么Autofac将有足够的信息来填充这些参数。

Func<T>没有无参数构造函数。如果你在VS中输入new Func<BillingStore>(,你会看到智能感知告诉你构造函数实际上接受一个对象和一个IntPtr。我猜你没有在你的集装箱里登记。

我进一步猜测你真正想要做的是使用Autofac为你提供的内置Func<T>关系类型,而不是你正在创建的工厂。如果您想要autofacc Func<T>,您只需要在函数中注册类型。奇迹发生了。它只是工作。在这种情况下,这意味着您只需要注册BillingStore并确保它可以被解析。

builder.RegisterType<BillingStore>();

如果我们把它们放在一起,更新后的代码看起来像这样:

void Main()
{
    var builder = new ContainerBuilder();
    builder.RegisterType<BillingStore>();
    builder.RegisterType<Consumer>().PropertiesAutowired();
    var container = builder.Build();
    var consumer = container.Resolve<Consumer>();
    // The BillingStoreFactory property is now populated
    // on the Consumer object you resolved.
}
public class BillingStore { }
public class Consumer
{
  public Func<BillingStore> BillingStoreFactory { get; set; }
}

我建议阅读Autofac中的隐式关系类型和属性注入支持。我们有很多文档和例子可以帮助你完成这个