Autofac 将参数注册到组件
当你使用 注册组件 时,你可以为基于该组件的 服务解决方案 提供一组参数。如果你更愿意在解决服务时提供参数,也可以 这样做。
可用的参数类型
Autofac 提供了几种不同的参数匹配策略:
NamedParameter
:按名称匹配目标参数TypedParameter
:按类型(精确类型匹配)匹配目标参数ResolvedParameter
:灵活参数匹配
NamedParameter
和 TypedParameter
只能提供常量值。
ResolvedParameter
可以用来动态地从容器中获取值,例如通过按名称解析服务。
使用反射组件的参数
当你注册一个基于反射的组件时,组件类型的构造函数可能需要一个无法从容器中解析的参数。你可以在注册时使用参数提供这个值。
假设你有一个需要传递配置节名称的配置读取器:
public class ConfigReader : IConfigReader
{
public ConfigReader(string configSectionName)
{
// 存储配置节名称
}
// ...根据节名称读取配置。
}
你可以使用 lambda 表达式组件来实现:
builder.Register(c => new ConfigReader("sectionName")).As<IConfigReader>();
或者为反射组件注册提供参数:
// 使用NAMED参数:
builder.RegisterType<ConfigReader>()
.As<IConfigReader>()
.WithParameter("configSectionName", "sectionName");
// 使用TYPED参数:
builder.RegisterType<ConfigReader>()
.As<IConfigReader>()
.WithParameter(TypedParameter.From("sectionName"));
// 使用RESOLVED参数:
builder.RegisterType<ConfigReader>()
.As<IConfigReader>()
.WithParameter(
new ResolvedParameter(
(pi, ctx) => pi.ParameterType == typeof(string) && pi.Name == "configSectionName",
(pi, ctx) => "sectionName"));
使用 lambda 表达式组件的参数
对于 lambda 表达式组件注册,你不是在注册时传递参数值,而是启用在服务解决时传递参数值的能力。( 更多关于带有参数的解决服务的信息 )
在组件注册表达式中,你可以利用传入的参数,使用泛型 lambda Register
方法:
builder.Register((MyConfig config) => new Worker(config));
如果你需要访问完整的参数列表,可以通过更改注册委托的签名来实现。不要将参数作为 lambda 的参数,而是接受一个 IComponentContext
和一个 IEnumerable<Parameter>
:
// 使用两个参数注册委托:
// c = 当前的 IComponentContext,用于动态解析依赖项
// p = 包含传入参数集的 IEnumerable<Parameter>
builder.Register((c, p) =>
new Worker(p.Named<MyConfig>("config")));
当 使用参数解析 时,你的 lambda 会使用传递的参数:
var customConfig = new MyConfig
{
SomeValue = "../"
};
var worker = scope.Resolve<Worker>(new NamedParameter("config", customConfig));