如何在不注册的情况下注入(inject)服务?
我的意思是过去一些 DI 框架会自动为 IService
注册 Service
。
我的情况是我有很多服务,基本上注册每一个服务都是一件很痛苦的事情。那么 asp.net 核心默认 DI 框架是否支持此功能?
最佳答案
我猜你喜欢它与 Autofac 一起工作的方式:
var assembly = typeof(MyModule).Assembly;
builder.RegisterAssemblyTypes(assembly)
.Where(t => t.Name.EndsWith("Service"))
.AsImplementedInterfaces()
.InstancePerLifetimeScope();
但是出于某些原因您不想切换到 Autofac(例如您希望使用外部库的扩展来注册它们的依赖项)。 所以我的建议是创建一些像下面这样使用反射的扩展:
public static IServiceCollection AddSingletonsByConvention(this IServiceCollection services, Assembly assembly, Func<Type, bool> interfacePredicate, Func<Type, bool> implementationPredicate)
{
var interfaces = assembly.ExportedTypes
.Where(x => x.IsInterface && interfacePredicate(x))
.ToList();
var implementations = assembly.ExportedTypes
.Where(x => !x.IsInterface && !x.IsAbstract && implementationPredicate(x))
.ToList();
foreach (var @interface in interfaces)
{
var implementation = implementations.FirstOrDefault(x => @interface.IsAssignableFrom(x));
if (implementation == null) continue;
services.AddSingleton(@interface, implementation);
}
return services;
}
public static IServiceCollection AddSingletonsByConvention(this IServiceCollection services, Assembly assembly, Func<Type, bool> predicate)
=> services.AddSingletonsByConvention(assembly, predicate, predicate);
现在您可以通过如下简单的代码注册您的所有服务:
var assembly = typeof(MyType).Assembly;
services.AddSingletonsByConvention(assembly, x => x.Name.EndsWith("Service"));
您可以随意自定义这些扩展以满足您的需求。 例如,如果您没有找到某些服务的实现,您可以引发异常,如果这会让您感觉更安全一些的话。
关于c# - 具有约定的内置依赖注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42180526/