如何使用条件装饰器通过委托工厂解析服务?

问题描述:

我有一个类hirerachy,看起来像这样:如何使用条件装饰器通过委托工厂解析服务?

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解决了IFoo时需要Func<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中?

您需要手动注册Func<IFoo>,明确地传递正确的参数到FooBar组件

builder.Register<Func<IFoo>>(c => 
    { 
     var ctx = c.Resolve<IComponentContext>(); 
     return() => new Foo(new Bar(() => ctx.Resolve<IFoo>(), ctx.ResolveNamed<IBaz>("baz"))); 
    }); 

如果你不想“新” FooBarRegister功能,它也可以通过解决它们从容器中实现,但代码看起来相当讨厌:

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"))))); 
    }); 
+0

这可以避免吗?因为在我的实际代码中,'Baz'和'BazDecorator'实际上在对象图中非常深,所以我想尽可能避免显式注册我的对象图的大部分。 – rexcfnghk

+0

对不起,我不能想到任何其他解决方案将需要更少的代码或更改您的原始代码... – tdragon

+0

没关系,感谢您的输入无论如何! – rexcfnghk