ASP.NET Core 2.0内置DI批量注册实现同一基类的数百服务类
Absolutely, you can skip writing hundreds of repetitive services.AddTransient lines by using reflection to scan your assembly and automatically register all your service classes. Here's a step-by-step solution tailored to your pattern:
Step 1: Target Your Service Pattern
Your services follow a consistent structure:
- They inherit from the generic
Service<TEntity>base class - They implement a unique non-generic interface (like
IClass1,IClass234)
We’ll use reflection to find all classes matching this pattern and register each against its specific interface.
Step 2: Add Batch Registration to ConfigureServices
In your Startup.cs file’s ConfigureServices method, add this code to scan and register your services in bulk:
public void ConfigureServices(IServiceCollection services) { // Keep your existing registrations (like MVC, database contexts) here // Get the assembly containing your service classes // Replace Class1 with any of your service classes to target the correct assembly var serviceAssembly = typeof(Class1).Assembly; // Filter and map valid service classes to their interfaces var serviceRegistrations = serviceAssembly.GetTypes() .Where(type => type.IsClass && !type.IsAbstract && // Only concrete classes type.BaseType != null && type.BaseType.IsGenericType && // Inherit from a generic base type.BaseType.GetGenericTypeDefinition() == typeof(Service<>)) // Base is Service<TEntity> .Select(type => new { ImplementationType = type, ServiceInterface = type.GetInterfaces() // Exclude the generic IService<TEntity> to find the specific interface .FirstOrDefault(iface => !iface.IsGenericType || iface.GetGenericTypeDefinition() != typeof(IService<>)) }) .Where(reg => reg.ServiceInterface != null); // Skip classes without a specific interface // Register each service interface with its implementation foreach (var reg in serviceRegistrations) { // Choose AddTransient, AddScoped, or AddSingleton based on your lifetime needs services.AddTransient(reg.ServiceInterface, reg.ImplementationType); } }
Key Details to Note:
- Assembly Targeting: Ensure
typeof(Class1).Assemblypoints to the correct assembly where all your service classes live. If services are spread across multiple assemblies, repeat this logic for each. - Lifetime Control: Swap
AddTransientwithAddScoped(per-request lifetime) orAddSingleton(single instance) depending on your application’s requirements. - Multiple Interfaces: If any service class implements more than one specific interface, replace
FirstOrDefaultwithWhereand loop through all matching interfaces to register each one.
Step 3: Confirm Constructor Injection Works
Your FoodController code will function exactly as before—no changes needed! The built-in DI will resolve each specific interface to its registered implementation:
public class FoodController : Controller { private readonly IClass1 _class1; private readonly IClass234 _class234; public FoodController(IClass1 class1, IClass234 class234) { _class1 = class1; _class234 = class234; } // Controller actions go here }
This approach keeps your ConfigureServices method clean and scalable, even as you add hundreds more service classes.
内容的提问来源于stack exchange,提问作者Train

