如何使用Scrutor将服务注册为IValidator对应的子接口实现类型?
问题原因
你的现有配置存在3个核心问题,和手动注册的行为不匹配:
- 使用了
RegistrationStrategy.Replace替换策略:该策略会覆盖同一接口的已注册实现,要注入多实现集合必须使用追加策略才能保留所有实现类。 - 调用了
AsImplementedInterfaces():该方法会把实现类注册到它所有实现的接口(包括父接口IValidator),而你手动注册时仅注册到子接口。 - 未过滤抽象类/接口:扫描过程可能会把接口本身、抽象实现类也加入注册列表,导致注入异常。
调整方案
方案1:明确分别注册两个子接口(逻辑清晰,适合子接口数量少的场景)
// 注册IFirstChildValidator的所有实现 services.Scan(scan => scan .FromAssemblyOf<IFirstChildValidator>() .AddClasses(classes => classes .InNamespaces("my.namespace") .AssignableTo<IFirstChildValidator>() .Where(t => !t.IsAbstract && !t.IsInterface)) .UsingRegistrationStrategy(RegistrationStrategy.Append) .As<IFirstChildValidator>() .WithScopedLifetime()); // 注册ISecondChildValidator的所有实现 services.Scan(scan => scan .FromAssemblyOf<ISecondChildValidator>() .AddClasses(classes => classes .InNamespaces("my.namespace") .AssignableTo<ISecondChildValidator>() .Where(t => !t.IsAbstract && !t.IsInterface)) .UsingRegistrationStrategy(RegistrationStrategy.Append) .As<ISecondChildValidator>() .WithScopedLifetime());
方案2:自动匹配所有IValidator的子接口(扩展性更强,新增子接口无需修改注册代码)
services.Scan(scan => scan .FromAssemblyOf<IValidator>() .AddClasses(classes => classes .InNamespaces("my.namespace") .AssignableTo<IValidator>() .Where(t => !t.IsAbstract && !t.IsInterface)) .UsingRegistrationStrategy(RegistrationStrategy.Append) .As(implType => implType.GetInterfaces() // 仅注册继承自IValidator的子接口,不注册父接口IValidator本身 .Where(iface => iface != typeof(IValidator) && typeof(IValidator).IsAssignableFrom(iface))) .WithScopedLifetime());
两种方案调整后都可以实现和你手动注册完全一致的效果,直接注入IEnumerable<IFirstChildValidator>、IEnumerable<ISecondChildValidator>即可拿到对应子接口的所有实现集合。
内容的提问来源于stack exchange,提问作者Maroun
相关产品推荐
相关产品推荐

