【问题标题】:Autofac Parameter injectionAutofac 参数注入
【发布时间】:2019-05-01 08:46:00
【问题描述】:

我误解了Autofac documentation 将参数传递给 Resolve 方法。以下是我的意思的简约示例:

示例

https://dotnetfiddle.net/fz5eTp

public static void Main()
{
  var cb = new ContainerBuilder();
  cb.RegisterType<A>();
  cb.Register<B>((c, p) => new B(p.TypedAs<C>()));
  using (var c = cb.Build())
  {
    // works
    c.Resolve<B>(TypedParameter.From(new C()));
    // fails
    c.Resolve<A>(TypedParameter.From(new C()));
  }
}
public class A { public A(B b) { } }
public class B { public B(C c) { } }
public class C { }

预期

我预计 TypedParameter 会被传递到 B 类。

不幸的是,异常消息“序列不包含元素”表明没有传递任何参数。

问题

如何将参数(仅在 Resolve 时知道)传递给较低级别​​的构造函数?或者在这个具体示例中,当解析 A 时,如何将 C 参数传递给 B

【问题讨论】:

  • 确保您的问题是独立的。请将所有相关代码 sn-ps 和异常详细信息作为问题的一部分。
  • @TravisIllig。 “弄清楚如何在运行时确定参数并将其包装在提供程序或 lamda 表达式注册中”-> 您能否指出如何为每次由不同 json 提供的对象实现的方向运行时间?
  • 我不明白你在问什么——“不同的 json”从哪里来? “在哪里”很重要。这是您需要在问题中包含的信息才能获得足够的答案。

标签: c# dependency-injection inversion-of-control autofac


【解决方案1】:

选项1

我能想到的最简单的方法是将解析过程分为两个步骤:

首先,您可以在运行时通过指定的已知C 值解析B,将其存储在myB 参考值中:

B myB = c.Resolve<B>(TypedParameter.From(new C()));

然后将myB 值传递给A 解析器:

A myA = c.Resolve<A>(TypedParameter.From(myB));

您可以在我的GitHub(带输出)中找到完整的工作示例。

选项2

如果你想在解析时写一行代码,你需要修改AB的寄存器:

cb.Register<A>((c, p) =>
{
    B myB = c.Resolve<B>(p);
    return new A(myB);
});
cb.Register<B>((c, p) => {
    C myC = p.Named<C>("myC");
    return new B(myC);
});

然后:

A myA = c.Resolve<A>(new NamedParameter("myC", new C()));

同样,您可以在我的GitHub(带输出)中找到完整的工作示例。

【讨论】:

  • 这些是非常有用的技术,它们清楚地帮助我更好地理解 Autofac。然而,他们违背了 IoC 的理念,不是吗?
  • @ThierryProst,你能解释一下原因吗?
  • 我绝不是这方面的专家,所以我将使用 Illig 指出的 autofac 文档中的话:“将 C 作为参数传递给 A 破坏了基于接口的解耦通过假设你“知道”整个依赖链是如何被解决的,开发和控制反转给你。”虽然您的方法在技术上非常正确并且实际上非常巧妙,但我想我必须以完全不同的方式考虑这个问题......
  • 没错,这是一个设计问题,我会更新我的答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多