【问题标题】:Resolve Autofac factory based on multiple constructors基于多个构造函数解析 Autofac 工厂
【发布时间】:2013-03-08 16:24:59
【问题描述】:

有人知道让这个测试工作缺少什么吗? 可惜它不能开箱即用。

class A { }

class B { public B(A a) { } }

class C { public C(B b) { } }

[Test]
public void SuperFactoryResolutionTest()
{
    var builder = new ContainerBuilder();            
    builder.RegisterType<B>();
    builder.RegisterType<C>();

    using (var container = builder.Build())
    {
        Assert.DoesNotThrow(() =>
        {
            var factory = container.Resolve<Func<A, C>>();
            var x = factory(new A());
        });
    }
}

【问题讨论】:

  • 我不清楚你的目标是什么。为什么不注册A,然后使用容器获取C的实例?
  • 在我的场景中,A 是客户端连接时由 TcpListener 返回的 TcpClient 实例...
  • 为什么不添加构造函数 public C(A a) : this(new B(a)) { } - 这清楚地表明了如何在给定 A 的情况下构造 C

标签: autofac


【解决方案1】:

不,Autofac 不支持此功能。

调用Resolve时只能传递直接依赖。因此,您不能在层次结构链的深处特别指定依赖关系。

无论如何,这违反了控制反转原则:C 应该只知道B,而不应该知道B 在某处使用了A。因此,当您要求C 时,您也不应该告诉使用哪个A

但是,您可以通过手动构建解析链来实现一些类似的效果:

这是你能得到的最接近的:

var intermediateFactory = container.Resolve<Func<B,C>>();
Func<A, C> factory = 
    a => intermediateFactory(container.Resolve<B>(TypedParameter.From(a)));
var x = factory(new A());

【讨论】:

  • 谢谢,但你的方法是我试图避免的。而且,我不认为这违反控制反转原则,因为我不是要求 C,我要求的是工厂 Func
  • 是的,您要的是工厂Func&lt;A, C&gt;,这意味着我有一个A 给我一个C,但问题是C 不知道A 所以也知道从 Autofac 的角度来看,这个工厂不会工作。另请参阅此问题:stackoverflow.com/questions/5741761/…。但是,您也可以在容器中注册您的手写 Func&lt;A,C&gt; 工厂:builder.RegisterType&lt;Func&lt;A, C&gt;&gt;(c =&gt; return a =&gt; c.Resolve&lt;Func&lt;B,C&gt;&gt;(c.Resolve&lt;B&gt;(TypedParameter.From(a))));
猜你喜欢
  • 1970-01-01
  • 2016-05-25
  • 2017-05-11
  • 1970-01-01
  • 2018-09-10
  • 1970-01-01
  • 1970-01-01
  • 2012-01-31
  • 2016-08-15
相关资源
最近更新 更多