我有一个班级雇佣队伍,看起来像这样:
public class Foo : IFoo
{
private readonly IBar _bar;
public Foo(IBar bar)
=> _bar = bar;
}
public class Bar : IBar
{
private readonly Func<IFoo> _fooFunc;
private readonly IBaz _baz;
public Bar(Func<IFoo> fooFunc, IBaz baz)
{
_fooFunc = fooFunc;
_baz = baz;
}
}
public class Baz : IBaz
{
}
public class BazDecorator : IBaz
{
private readonly IBaz _decoratee;
public BarDecorator(IBaz decoratee)
=> _decoratee = decoratee;
}
请注意Bar
直接使用Func<IFoo>
代替IFoo
,因为解析IFoo
时存在循环依赖关系。
我目前的注册看起来像这样:
public class MyModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<Foo>().As<IFoo>();
builder.RegisterType<Bar>().As<IBar>();
// Func<IFoo> is automatically resolved in AutoFac
builder.RegisterType<Baz>().Named<IBaz>("baz");
builder.RegisterDecorator<IBaz>((c, inner) =>
new BazDecorator(inner),
fromKey: "baz");
}
}
我希望仅在通过BazDecorator
而不是 Foo
解析时有条件地注册Func<IFoo>
,如下:
Foo------Bar-----BazDecorator----Baz
\
\
\____Foo----Bar----Baz
如何在AutoFac中注册我的服务?
答案 0 :(得分:2)
您需要手动注册Func<IFoo>
,以便将明确的参数明确传递给Foo
和Bar
组件
builder.Register<Func<IFoo>>(c =>
{
var ctx = c.Resolve<IComponentContext>();
return () => new Foo(new Bar(() => ctx.Resolve<IFoo>(), ctx.ResolveNamed<IBaz>("baz")));
});
如果您不想在Foo
函数中使用“new”Bar
和Register
,也可以通过从容器中解析它们来实现,但代码看起来非常讨厌:
builder.Register<Func<IFoo>>(c =>
{
var ctx = c.Resolve<IComponentContext>();
return () => ctx.Resolve<IFoo>(
new ResolvedParameter(
(p, cx) => p.Name == "bar",
(p, cx) => cx.Resolve<IBar>(new ResolvedParameter(
(p1, c1) => p1.Name == "baz",
(p1, c1) => c1.ResolveNamed<IBaz>("baz")))));
});