Castle.Windsor的DependsOn Dependency.OnValue在Microsoft DI中的等效实现
从Castle.Windsor迁移到Microsoft.Extensions.DependencyInjection的等效配置
原Castle.Windsor配置
原.NET Standard 2.0类库中的Castle.Windsor依赖注入配置:
container.Register(Component.For<IMyFactory>() .ImplementedBy<MyFactory>() .DependsOn(Dependency.OnValue("connectionString", container.Resolve<IDataAccess>().ConnectionString)) .LifestyleSingleton()); container.Register(Component.For<IMyAdapter>() .ImplementedBy<MyAdapter>().LifestyleTransient());
等效的Microsoft.Extensions.DependencyInjection写法
基础注册:IMyAdapter
IMyAdapter的Transient生命周期注册非常直接,对应Castle.Windsor的LifestyleTransient():
services.AddTransient<IMyAdapter, MyAdapter>();
IMyFactory的单例注册及依赖处理
IMyFactory是单例生命周期(对应Castle.Windsor的LifestyleSingleton()),且需要注入从IDataAccess获取的连接字符串,有两种实现方式:
方式1:使用工厂方法注册
通过工厂方法直接从服务提供者中解析IDataAccess,提取连接字符串后实例化MyFactory:
services.AddSingleton<IMyFactory>(serviceProvider => new MyFactory(serviceProvider.GetRequiredService<IDataAccess>().ConnectionString));
方式2:构造函数注入(推荐)
如果可以修改MyFactory的构造函数,让它直接依赖IDataAccess而非字符串参数,会更符合依赖注入的设计原则,也更易于测试:
// 修改后的MyFactory类 public class MyFactory : IMyFactory { private readonly string _connectionString; public MyFactory(IDataAccess dataAccess) { _connectionString = dataAccess.ConnectionString; } // 后续业务逻辑中使用_connectionString } // 此时注册简化为: services.AddSingleton<IMyFactory, MyFactory>();
完整配置示例
假设IDataAccess已提前注册到容器中,完整的DI配置如下:
// 先注册IDataAccess(示例) // services.AddSingleton<IDataAccess, DataAccessImpl>(); // 注册IMyAdapter services.AddTransient<IMyAdapter, MyAdapter>(); // 注册IMyFactory(二选一) // 方式1:工厂方法 services.AddSingleton<IMyFactory>(sp => new MyFactory(sp.GetRequiredService<IDataAccess>().ConnectionString)); // 方式2:构造函数注入(修改MyFactory后使用) // services.AddSingleton<IMyFactory, MyFactory>();
注意事项
- 必须确保
IDataAccess已经提前注册到IServiceCollection中,否则GetRequiredService<IDataAccess>()会抛出InvalidOperationException。 - 优先选择构造函数注入的方式,它能避免直接依赖服务提供者,让代码的依赖关系更清晰,也更便于单元测试。
内容的提问来源于stack exchange,提问作者tRuEsAtM
相关产品推荐
相关产品推荐

