如何使用Func <t>作为注入属性

时间:2015-07-27 21:22:47

标签: c# dependency-injection autofac

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

AutoFac配置:

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

公共财产:

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

我没有看到我做错了什么,我通常会尽量避免代表,但这次我不能。

2 个答案:

答案 0 :(得分:2)

定义不带static关键字的属性

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

答案 1 :(得分:2)

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

首先,让我们完善代码示例,以便我们讨论一下。我假设你有类似的东西:

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的意思是说,&#34;当我解析这个对象时,我希望你也注入它的属性。&#34;现在你在函数/工厂上有这个,所以Autofac将尝试在 Func<BillingStore>上注入属性,而不是 Func<BillingStore>类型的属性 。您希望使用属性 - 消费对象在上填充属性。

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

问题3:您的功能注册无法正常工作。如果您进行RegisterType<T>调用,则意味着Autofac将能够自动找出参数T - 要么它不接受任何构造函数参数,要么Autofac将有足够的信息来填充这些参数。

Func<T>没有无参数构造函数。如果您在VS中键入new Func<BillingStore>(,您会看到IntelliSense显示构造函数实际上是一个对象和一个IntPtr。我猜你没有在你的容器中注册。

我进一步猜测你真正想要做的是使用内置的Func<T> relationship type that Autofac provides for you而不是你正在创建的工厂。 如果您需要Autofac Func<T>,则只需在功能中注册该类型。 Magic会发生。它只是有效。在这种情况下,这意味着您只需要注册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中的implicit relationship typesproperty injection support我们有很多文档可以帮助您解决这个问题。