在autofac中注册装饰器而无需手动指定所有依赖项

Rub*_*ben 14 c# dependency-injection decorator autofac

我有一个装饰器,有一些其他依赖项,也应该使用容器解决.例:

public class FooDecorator : IFoo
{
    public FooDecorator(IFoo inner, IBar bar, IBaz baz)
}
Run Code Online (Sandbox Code Playgroud)

我可以这样注册:

builder.RegisterType<Foo>().As<IFoo>();
builder.RegisterDecorator<IFoo>((c, inner) => 
    new FooDecorator(inner, c.Resolve<IBar>(), c.Resolve<IBaz>()), "key");
Run Code Online (Sandbox Code Playgroud)

这是有效的,但不是很好,我必须手动指定所有其他依赖项.我想做的是:

builder.RegisterDecorator<FooDecorator, IFoo>("key");
Run Code Online (Sandbox Code Playgroud)

IFoo其解析为'inner',IFoo并从容器中解析其他依赖项.这是可能的,还是我可以用Func注册装饰器会导致这种行为?

Cyr*_*and 14

为了避免手动指定所有依赖项,您应该在Autofac中注册装饰器并在RegisterDecorator方法的第一个参数内解析它.

builder.RegisterType<Foo>()
       .Named<IFoo>("original");
builder.RegisterType<FooDecorator>()
       .Named<IFoo>("decorator");
builder.RegisterDecorator<IFoo>((c, inner) => c.ResolveNamed<IFoo>("decorator", TypedParameter.From(inner)), "original")
       .As<IFoo>();
Run Code Online (Sandbox Code Playgroud)

使用命名注册注册装饰器将避免任何冲突.

  • 这太棒了,但是如果您不知道(或不关心)“IFoo”的具体实现是“Foo”怎么办?是否可以声明类似“用 `FooDecorator` 装饰当前解析为 `IFoo` 的任何内容”的内容?(假设 IFoo 之前已注册以提供“IFoo”,但不一定作为_named_服务) - PS我认为这也是OP正在寻找的 (2认同)

inc*_*lly 5

根据Ezolotko的回答,我进行了扩展。

public static void RegisterDecorator<TInterface, TImplementation, TDecorator>
    (this ContainerBuilder builder) 
    where TImplementation : TInterface 
    where TDecorator : TInterface
    {
        var innerImplementationName = $"{typeof(TImplementation).Name} as implementation";
        var decoratorName = $"{typeof(TDecorator).Name} as decorator";

        builder.RegisterType<TImplementation>().Named<TInterface>(innerImplementationName);
        builder.RegisterType<TDecorator>().Named<TInterface>(decoratorName);
        builder.RegisterDecorator<TInterface>((c, inner) => c.ResolveNamed<TInterface>(decoratorName, TypedParameter.From(inner)), innerImplementationName);
    }
}
Run Code Online (Sandbox Code Playgroud)

我内心的书呆子深深地体会到,我们都很好地装饰了彼此对装饰器这个问题的回答。

编辑

Autofac v4.9添加了RegisterDecorator功能。看看,真棒。