Windsor中如何根据字符串注册并解析泛型IImportCommand系列命令对象
完全可以通过Windsor容器实现,该方案可以彻底消除硬编码的switch语句,后续新增导入类型时无需修改原有创建逻辑,符合开闭原则,具体实现步骤如下:
步骤1:补充非泛型基础接口(可选但推荐)
为了统一处理不同泛型参数的命令赋值逻辑,先新增非泛型的基础接口,避免后续使用反射或dynamic带来的类型安全问题:
public interface IImportCommand { DateTime Date { get; set; } // 统一设置Items的方法,入参适配你JSON反序列化的结构 void SetItems(IEnumerable<JToken> data); }
注:如果你的项目使用System.Text.Json做JSON处理,只需将
JToken替换为JsonElement,适配对应的反序列化逻辑即可。
修改原有泛型接口继承该非泛型接口:
public interface IImportCommand<T> : IImportCommand where T : ImportModelBase { List<T> Items { get; set; } }
在泛型实现类ImportEntityCommand<T>中实现SetItems方法:
public class ImportEntityCommand<T> : ICommand, IImportCommand<T> where T : ImportModelBase { public DateTime Date { get; set; } public List<T> Items { get; set; } public void SetItems(IEnumerable<JToken> data) { Items = data.Select(d => d.ToObject<T>()).ToList(); } }
步骤2:启用Windsor类型化工厂支持
Windsor的TypedFactoryFacility可以自动帮我们实现工厂接口,无需手写工厂实现类:
// 容器初始化时启用类型化工厂设施 container.AddFacility<TypedFactoryFacility>();
步骤3:注册命令类型与工厂
按你传入的字符串标识作为组件名称,注册对应的具体命令类,同时注册命令工厂:
container.Register( // 按字符串key命名注册具体命令类 Component.For<ImportUserCommand>().Named("user"), Component.For<ImportPersonCommand>().Named("person"), // 注册工厂,Windsor会自动生成实现类 Component.For<IImportCommandFactory>().AsFactory() );
其中工厂接口定义如下,不需要手动写实现:
public interface IImportCommandFactory { // 入参对应注册时的组件名称,Windsor会自动返回对应实例 ICommand Create(string type); }
步骤4:业务逻辑中使用
建议通过构造函数注入IImportCommandFactory,使用时仅需几行代码即可完成动态创建与赋值:
var command = (IImportCommand)_commandFactory.Create(typeString); command.Date = body.Date.ToUniversalTime(); command.SetItems(body.Data);
方案优势
- 无硬编码switch逻辑,后续新增导入类型仅需新增对应模型、命令类,再加一行注册代码即可,原有逻辑零修改
- 公共赋值逻辑统一维护,无重复代码
- 全类型安全,无运行时转换风险
内容的提问来源于stack exchange,提问作者demo
相关产品推荐
相关产品推荐

