Simple Injector 4.1:如何基于新版API重写参数注入行为?
在Simple Injector 4.1+中实现值类型参数注入
嘿,我完全懂你碰到的困扰——之前依赖旧博客的方法,结果Simple Injector更新后API变了,IDependencyInjectionBehavior.BuildExpression被弃用,换成了GetInstanceProducer,确实让人有点懵。不过别担心,我来一步步教你怎么在新版里实现值类型(比如连接字符串这类)的注入。
首先,我们需要实现自定义的IDependencyInjectionBehavior,核心就是重写GetInstanceProducer方法,让容器能正确解析值类型的参数。下面是具体的实现思路和代码:
步骤1:创建自定义的依赖注入行为类
这个类会继承DependencyInjectionBehavior(Simple Injector提供的默认实现),然后重写GetInstanceProducer方法,针对值类型参数做特殊处理:
using SimpleInjector; using SimpleInjector.Advanced; using System; using System.Reflection; public class ValueTypeInjectionBehavior : DependencyInjectionBehavior { private readonly Container _container; private readonly Func<ParameterInfo, InstanceProducer> _valueProducerFactory; public ValueTypeInjectionBehavior(Container container, Func<ParameterInfo, InstanceProducer> valueProducerFactory) : base(container) { _container = container ?? throw new ArgumentNullException(nameof(container)); _valueProducerFactory = valueProducerFactory ?? throw new ArgumentNullException(nameof(valueProducerFactory)); } protected override InstanceProducer GetInstanceProducer(ParameterInfo parameter, bool throwOnFailure) { // 先检查是否是值类型或者字符串(字符串是引用类型但我们也想处理) if (parameter.ParameterType.IsValueType || parameter.ParameterType == typeof(string)) { var producer = _valueProducerFactory(parameter); if (producer != null) { return producer; } } // 不是值类型的话,回退到默认行为 return base.GetInstanceProducer(parameter, throwOnFailure); } }
步骤2:注册自定义行为到容器
接下来,我们需要把这个自定义行为替换掉容器的默认行为,同时定义一个工厂方法来提供值类型参数对应的实例生产者。比如我们要注入连接字符串,可以这么做:
var container = new Container(); // 注册我们的自定义注入行为 container.Options.DependencyInjectionBehavior = new ValueTypeInjectionBehavior( container, parameter => { // 这里可以根据参数名称或者类型来匹配值 if (parameter.Name == "connectionString" && parameter.ParameterType == typeof(string)) { // 从配置中获取连接字符串,这里只是示例,你可以换成自己的配置读取逻辑 string connectionString = "Your_Connection_String_Here"; return Lifestyle.Singleton.CreateProducer(parameter.ParameterType, () => connectionString, container); } // 如果没有匹配到,返回null,让默认行为处理 return null; });
步骤3:测试注入效果
现在你就可以正常注册依赖,容器会自动注入值类型参数了。比如有个服务需要连接字符串:
public class DatabaseService { private readonly string _connectionString; public DatabaseService(string connectionString) { _connectionString = connectionString; } // ... 其他方法 } // 注册服务 container.Register<DatabaseService>(); // 解析服务时,连接字符串会被自动注入 var service = container.GetInstance<DatabaseService>();
额外说明
- 你可以根据自己的需求扩展
valueProducerFactory的逻辑,比如根据参数的特性(比如自定义[InjectValue]特性)来匹配,或者从配置文件、环境变量中读取值,这样更灵活。 - 记得要确保值类型的实例生产者是正确的生命周期,比如连接字符串这类不会变的,用
Lifestyle.Singleton就很合适。
内容的提问来源于stack exchange,提问作者Casper
相关产品推荐
相关产品推荐

