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)
使用命名注册注册装饰器将避免任何冲突.
根据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功能。看看,真棒。
| 归档时间: |
|
| 查看次数: |
3458 次 |
| 最近记录: |