.NET 6依赖注入中如何获取指定的MyClass实例?
.NET 6中获取依赖注入里指定的MyClass实例
你当前的注册方式会把两个MyClass实例都添加到服务集合中,但默认GetService<MyClass>()只会返回最后注册的那个(依赖ClassB的实例)。要获取指定的实例,有几种可行方案:
方案1:使用自定义命名服务扩展
.NET 6没有原生命名服务支持,我们可以自己实现扩展来按名称区分实例:
首先添加扩展类和辅助类:
public static class NamedServiceExtensions { public static IServiceCollection AddNamedSingleton<TService>(this IServiceCollection services, string name, Func<IServiceProvider, TService> factory) { services.AddSingleton(sp => new NamedService<TService>(name, factory(sp))); return services; } public static TService GetNamedService<TService>(this IServiceProvider provider, string name) { return provider.GetServices<NamedService<TService>>() .First(s => s.Name == name) .Service; } } public class NamedService<TService> { public string Name { get; } public TService Service { get; } public NamedService(string name, TService service) { Name = name; Service = service; } }
修改注册代码:
public void ConfigureServices(IServiceCollection services) { services.AddNamedSingleton<MyClass>("ClassA", sp => new MyClass(new ClassA())); services.AddNamedSingleton<MyClass>("ClassB", sp => new MyClass(new ClassB())); }
获取指定实例:
var classAInstance = serviceProvider.GetNamedService<MyClass>("ClassA"); var classBInstance = serviceProvider.GetNamedService<MyClass>("ClassB");
方案2:使用包装类标记实例
创建继承自MyClass的包装类,用类型区分不同实例:
public class MyClassWithA : MyClass { public MyClassWithA(ClassA classA) : base(classA) { } } public class MyClassWithB : MyClass { public MyClassWithB(ClassB classB) : base(classB) { } }
注册包装类:
public void ConfigureServices(IServiceCollection services) { services.AddSingleton<MyClassWithA>(); services.AddSingleton<MyClassWithB>(); }
按包装类类型获取实例:
var classAInstance = serviceProvider.GetService<MyClassWithA>(); var classBInstance = serviceProvider.GetService<MyClassWithB>();
方案3:遍历实例并筛选
如果不想修改注册逻辑,可以先获取所有MyClass实例,再根据内部依赖类型筛选。首先把MyClass的私有字段改为公共只读属性:
public class MyClass { public IMyInterface MyInterface { get; } public MyClass(IMyInterface interfaceInstance) { MyInterface = interfaceInstance; } // ...其他代码 }
获取并筛选实例:
var allInstances = serviceProvider.GetServices<MyClass>(); var classAInstance = allInstances.FirstOrDefault(m => m.MyInterface is ClassA); var classBInstance = allInstances.FirstOrDefault(m => m.MyInterface is ClassB);
内容的提问来源于stack exchange,提问作者CodeMonkey
相关产品推荐
相关产品推荐

