我猜你喜欢它使用 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"));
随意自定义这些扩展程序以满足您的需求。
例如,如果您找不到某些服务的实现,则可以触发异常,如果这会让您感觉更安全一些。