我有一个装饰器,有一些其他依赖项,也应该使用容器解决。
例:
public class FooDecorator : IFoo
{
public FooDecorator(IFoo inner, IBar bar, IBaz baz)
}
我可以这样注册:
builder.RegisterType<Foo>().As<IFoo>();
builder.RegisterDecorator<IFoo>((c, inner) =>
new FooDecorator(inner, c.Resolve<IBar>(), c.Resolve<IBaz>()), "key");
这是有效的,但不是很好,我必须手动指定所有其他依赖项。我想做的是:
builder.RegisterDecorator<FooDecorator, IFoo>("key");
在哪里 IFoo 被解决了'内在' IFoo 并从容器中解析其他依赖项。这是可能的,还是我可以用Func注册装饰器,这将导致这种行为?
为了避免手动指定所有依赖项,您应该在中注册装饰器 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>();
使用命名注册注册装饰器将避免任何冲突。
为了避免手动指定所有依赖项,您应该在中注册装饰器 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>();
使用命名注册注册装饰器将避免任何冲突。
根据Cyril Durand的回答,这里是注册装饰器的通用辅助方法:
private void RegisterDecorator<TInterface, TImplementation, TDecorator>(ContainerBuilder builder) where TImplementation : TInterface where TDecorator : TInterface
{
builder.RegisterType<TImplementation>().Named<TInterface>("implementation");
builder.RegisterType<TDecorator>().Named<TInterface>("decorator");
builder.RegisterDecorator<TInterface>((c, inner) => c.ResolveNamed<TInterface>("decorator", TypedParameter.From(inner)), "implementation");
}
如果需要多个嵌套装饰器,可以引入具有更多通用参数(TDecorator1,TDecorator2等)的类似方法。