ISchemeSchedulePaymentFile scheduleFile = container.ResolveKeyed<ISchemeSchedulePaymentFile>(iocFileKey);
- ISchemeSchedulePaymentFile:接口与抽象
接口(Interface):ISchemeSchedulePaymentFile 是一个接口,定义了某些方法或属性的契约。
依赖抽象原则:通过接口解耦,代码依赖抽象而非具体实现,提高可维护性和可测试性。
- container:IoC容器
容器的作用:container 是一个IoC容器(如Unity、Autofac、DryIoc等),负责管理对象的创建、生命周期及依赖注入。
核心功能:
注册(Register):将接口与实现类关联,并可附加键(Key)或其他条件。
解析(Resolve):根据接口和键获取具体实例。
3. ResolveKeyed(key):键控解析
方法定义:ResolveKeyed(object key) 是IoC容器的方法,用于根据**键(Key)**解析接口的特定实现。
键(Key)的作用:
当同一接口有多个实现时,通过键区分不同的注册。例如:
// 注册时指定键(Unity示例)
container.RegisterType<ISchemeSchedulePaymentFile, XmlFileParser>("xml");
container.RegisterType<ISchemeSchedulePaymentFile, CsvFileParser>("csv");
`
解析逻辑:
当调用 ResolveKeyed(“csv”) 时,容器返回与键 “csv” 关联的 CsvFileParser 实例。
- iocFileKey:动态选择实现
键的传递:iocFileKey 是一个变量,可能是字符串、枚举或对象,用于在运行时动态决定使用哪个接口实现。
场景示例:
根据配置文件、用户输入或业务逻辑动态选择文件解析方式(如XML、CSV、JSON)。
- 依赖注入模式
服务定位模式(Service Locator):
此代码通过直接调用 container.ResolveKeyed 获取依赖实例,属于服务定位模式。
优点:灵活,适合动态选择实现。
缺点:隐藏类依赖,可能增加代码与容器的耦合,需谨慎使用。
对比构造函数注入:
更推荐的方式是在构造函数中声明依赖,由容器自动注入:
public class MyService
{
private readonly ISchemeSchedulePaymentFile _fileParser;
public MyService(ISchemeSchedulePaymentFile fileParser)
{
_fileParser = fileParser; // 容器自动注入
}
}
- 生命周期管理
实例生命周期:
解析的实例可能是:
瞬态(Transient):每次解析创建一个新实例。
单例(Singleton):整个容器共享一个实例。
作用域(Scoped):在特定作用域内共享实例(如Web请求)。
注册时指定生命周期(以Unity为例):
container.RegisterType<ISchemeSchedulePaymentFile, CsvFileParser>(
"csv",
new ContainerControlledLifetimeManager() // 单例
项目中用到这句。
var container = AutofacHostFactory.Container?.BeginLifetimeScope();
- 异常处理
可能的异常:
ResolutionFailedException:未找到对应键或类型的注册。
InvalidCastException:解析的实现类未实现接口。
防御性代码:
if (container.IsRegistered<ISchemeSchedulePaymentFile>(iocFileKey))
{
var fileParser = container.ResolveKeyed<ISchemeSchedulePaymentFile>(iocFileKey);
}