依赖注入:LightInject与UnityContainer按名称解析服务问题咨询
嗨,我之前切换DI容器的时候也碰到过一模一样的问题!Autofac的按名称解析确实太顺手了,换LightInject和Unity的时候很容易因为API差异踩坑。其实你没遗漏什么核心概念,就是这两个容器的命名服务解析方式和Autofac不一样,我给你分别说清楚:
LightInject 按名称解析服务
首先确认注册环节你是不是这么做的(应该是对的,但再核对下):
// 注册两个同接口服务,指定不同名称 container.Register<ILogger, FileLogger>(name: "FileLogger"); container.Register<ILogger, DatabaseLogger>(name: "DatabaseLogger");
解析的时候,不能直接用无参的GetInstance<ILogger>(),得明确传入名称参数:
// 解析指定名称的服务 var fileLogger = container.GetInstance<ILogger>("FileLogger"); var dbLogger = container.GetInstance(typeof(ILogger), "DatabaseLogger");
如果你用GetAllInstances<ILogger>()拿到了所有实例,也可以通过ServiceRegistration的Name属性筛选目标服务:
var allLoggers = container.GetAllInstances<ILogger>(); var targetLogger = allLoggers.First(l => container.GetServiceRegistration(l.GetType()).Name == "FileLogger");
UnityContainer 按名称解析服务
Unity的注册方式和你之前做的应该一致:
// 注册命名服务 container.RegisterType<ILogger, FileLogger>("FileLogger"); container.RegisterType<ILogger, DatabaseLogger>("DatabaseLogger");
解析的关键是用带名称参数的Resolve重载,而不是无参的Resolve<ILogger>():
// 解析指定名称的服务 var fileLogger = container.Resolve<ILogger>("FileLogger"); var dbLogger = container.Resolve(typeof(ILogger), "DatabaseLogger");
如果想从所有实例里筛选,Unity可以用ResolveAll<ILogger>()拿到全部,再结合注册信息匹配:
var allLoggers = container.ResolveAll<ILogger>(); // 通过注册信息定位目标服务 var targetRegistration = container.Registrations .First(r => r.RegisteredType == typeof(ILogger) && r.Name == "FileLogger"); var targetLogger = (ILogger)container.Resolve(targetRegistration.MappedToType);
总结一下:Autofac用ResolveNamed,而LightInject是GetInstance带名称参数,Unity是Resolve带名称参数——核心都是要在解析时明确指定你注册时用的名称,而不是默认拿第一个注册的实例或者全部实例。
内容的提问来源于stack exchange,提问作者Binesh Nambiar C
相关产品推荐
相关产品推荐

