Accurately master .NET dependency injection: DI automatic registration service is easily handled
Overview:.NET Dependency Injection (DI) automatically registers services through reflection. The example shows the registration of specified classes, classes with characteristics, and classes implemented by all interfaces under the project. Simplify configuration and improve maintainability.
In .NET, automatic registration of dependency injection (DI) can be done through reflection mechanism and assembly scanning to fulfill. The following are detailed steps and corresponding C# source code examples, including registering specified classes, registering classes with custom attributes, and registering all classes with interface implementations under the project (all interfaces under the project):
Step 1: Create interface and implementation classes
//Interface 1
public interface IService1
{
void PerformService1();
}
//Interface 2
public interface IService2
{
void PerformService2();
}
// Implement class 1, implement IService1
public class MyService1 : IService1
{
public void PerformService1()
{
Console.WriteLine("Service 1 performed.");
}
}
// Implement class 2, implement IService2
[CustomRegistration] // With custom attributes
public class MyService2 : IService2
{
public void PerformService2()
{
Console.WriteLine("Service 2 performed.");
}
}
// Implement class 3, implement IService1 and IService2
public class MyService3 : IService1, IService2
{
public void PerformService1()
{
Console.WriteLine("Service 3 (Service 1 part) performed.");
}
public void PerformService2()
{
Console.WriteLine("Service 3 (Service 2 part) performed.");
}
}
Step 2: Create custom attributes
// Custom attributes
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
sealed class CustomRegistrationAttribute : Attribute
{
}
Step 3: Create an automatic registration method
using System;
using System.Linq;
using System.Reflection;
using Microsoft.Extensions.DependencyInjection;
class Program
{
static void Main()
{
//Create service collection
var services = new ServiceCollection();
// Step 4: Register the specified class
services.AddTransient();
// Step 5: Register the class with custom attributes
RegisterClassesWithAttribute(services);
// Step 6: Register all classes with interface implementations under the project (all interfaces under the project)
RegisterAllImplementationsOfInterfaces(services);
// Build the service provider
var serviceProvider = services.BuildServiceProvider();
// Step 7: Use the registered service
var myService1 = serviceProvider.GetService();
myService1.PerformService1();
var myService2 = serviceProvider.GetService();
myService2.PerformService2();
var myService3 = serviceProvider.GetService();
myService3.PerformService1();
myService3.PerformService2();
}
// Automatically register classes with specified attributes
static void RegisterClassesWithAttribute(IServiceCollection services)
where TAttribute : Attribute
{
// Get the current assembly
var assembly = Assembly.GetExecutingAssembly();
// Get all classes with specified attributes
var attributedTypes = assembly.GetTypes()
.Where(type => type.GetCustomAttributes(typeof(TAttribute), true).Any() && type.IsClass);
//Register these classes
foreach (var attributedType in attributedTypes)
{
services.AddTransient(attributedType);
}
}
// Automatically register all classes with interface implementations under the project (all interfaces under the project)
static void RegisterAllImplementationsOfInterfaces(IServiceCollection services)
{
// Get the current assembly
var assembly = Assembly.GetExecutingAssembly();
// Get all interfaces under the project
var interfaceTypes = assembly.GetTypes()
.Where(type => type.IsInterface);
// Get all classes that implement these interfaces
var implementationTypes = assembly.GetTypes()
.Where(type => interfaceTypes.Any(interfaceType => interfaceType.IsAssignableFrom(type)) && type.IsClass);
//Register these classes
foreach (var implementationType in implementationTypes)
{
services.AddTransient(implementationType);
}
}
}
In the above code:
- Registered usingAddTransient method Specific MyService1 class.
- Registered usingRegisterClassesWithAttribute method A class with the CustomRegistrationAttribute attribute. The reflection mechanism is used here to dynamically obtain the types of all classes with specified characteristics and register them in the DI container.
- Registered usingRegisterAllImplementationsOfInterfaces All classes under the project that implement the interface.
Please make sure you reference it in the project
Microsoft.Extensions.DependencyInjection related packages. This is a basic example, real applications may require more complex configurations, depending on the needs of the project.
oicq.net