DryIoc中如何处理含运行时参数的工厂方法作为构造参数
我有一个实例构造函数,它接收一个String作为运行时参数,后续还有多个服务参数。我希望能在运行时指定该字符串,其余参数由DryIoc自动处理。StackOverflow上的一篇回答展示了简单解析场景的实现方式,但当包含工厂方法参数的对象本身作为构造函数参数时,解析会失败——因为DryIoc会尝试解析该字符串参数。
代码示例如下:
public class BigBrother { public BigBrother(Camera camera) { // Is watching you } } public class Camera { public Camera(Func<String, Incident> incidentFactory) { var incident = incidentFactory("Something bad was seen"); } } public class Incident { private String _title; public Incident(String title, ICctvService cctvService, IUserService userService, ILoggingService logger) { _title = title; // Things happened } }
此时解析BigBrother会失败,原因是Camera的参数无法被解析。请问是否有可行的解决办法?
解决办法
DryIoc 默认无法自动推断Func<String, Incident>这类带运行时参数的委托,需要显式配置容器,明确如何结合动态参数与自动注入的服务来创建实例。
1. 注册基础服务依赖
先确保所有需要自动注入的服务已在容器中注册:
var container = new Container(); container.Register<ICctvService, CctvService>(); container.Register<IUserService, UserService>(); container.Register<ILoggingService, LoggingService>();
2. 显式注册工厂委托
通过RegisterDelegate告诉容器如何生成Func<String, Incident>,将运行时字符串参数传递给Incident的构造函数,同时自动注入其他服务:
container.RegisterDelegate<Func<String, Incident>>(resolver => title => resolver.Resolve<Incident>(Typed.Of<string>(title)));
这里Typed.Of<string>(title)是DryIoc传递特定类型运行时参数的标准方式,确保容器不会尝试解析string类型的服务,而是使用传入的动态值。
3. 注册并解析目标对象
最后注册Camera和BigBrother,即可正常解析:
container.Register<Camera>(); container.Register<BigBrother>(); var bigBrother = container.Resolve<BigBrother>();
简化方案:启用自动工厂生成
如果不想手动注册委托,可以在容器初始化时开启自动工厂支持,让DryIoc自动生成带参数的委托:
var container = new Container(rules => rules.WithFactorySelector(Rules.SelectLastRegisteredFactory()));
开启后,只需注册基础服务和Camera、BigBrother,容器会自动处理Func<String, Incident>的生成逻辑。注意这种方式要求Incident的构造函数中string参数的类型唯一,避免参数匹配歧义。
内容的提问来源于stack exchange,提问作者Richard Petheram

