最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

全面解析.NET中的依賴注入(DI)

 更新時(shí)間:2025年06月26日 08:48:48   作者:百錦再@新空間  
依賴注入是一種軟件設(shè)計(jì)模式,其核心思想是將對象依賴關(guān)系的管理交由外部容器負(fù)責(zé),而不是由對象自身管理,下面小編就來和大家詳細(xì)介紹一下依賴注入吧

一、依賴注入核心原理

1. 控制反轉(zhuǎn)(IoC)與DI關(guān)系

  • 控制反轉(zhuǎn)(IoC):框架控制程序流程,而非開發(fā)者
  • 依賴注入(DI):IoC的一種實(shí)現(xiàn)方式,通過外部提供依賴對象

2. .NET DI核心組件

  • IServiceCollection:服務(wù)注冊容器
  • IServiceProvider:服務(wù)解析器
  • ServiceDescriptor:服務(wù)描述符(包含生命周期信息)

二、服務(wù)生命周期

三種生命周期類型

生命周期描述適用場景
Transient每次請求創(chuàng)建新實(shí)例輕量級(jí)、無狀態(tài)服務(wù)
Scoped同一作用域內(nèi)共享實(shí)例Web請求上下文
Singleton全局單例配置服務(wù)、緩存
// 注冊示例
services.AddTransient<ITransientService, TransientService>();
services.AddScoped<IScopedService, ScopedService>();
services.AddSingleton<ISingletonService, SingletonService>();

三、DI容器實(shí)現(xiàn)原理

1. 服務(wù)注冊流程

public static IServiceCollection AddTransient<TService, TImplementation>(this IServiceCollection services)
{
    // 創(chuàng)建服務(wù)描述符
    var descriptor = new ServiceDescriptor(
        typeof(TService),
        typeof(TImplementation),
        ServiceLifetime.Transient);
    
    // 添加到集合
    services.Add(descriptor);
    return services;
}

2. 服務(wù)解析流程

public object GetService(Type serviceType)
{
    // 1. 查找服務(wù)描述符
    var descriptor = _descriptors.FirstOrDefault(d => d.ServiceType == serviceType);
    
    // 2. 根據(jù)生命周期創(chuàng)建實(shí)例
    if (descriptor.Lifetime == ServiceLifetime.Singleton)
    {
        if (_singletons.TryGetValue(serviceType, out var instance))
            return instance;
        
        instance = CreateInstance(descriptor);
        _singletons[serviceType] = instance;
        return instance;
    }
    // ...處理Scoped和Transient
}

四、高級(jí)實(shí)現(xiàn)方法

1. 工廠模式注冊

services.AddTransient<IService>(provider => {
    var otherService = provider.GetRequiredService<IOtherService>();
    return new ServiceImpl(otherService, "參數(shù)");
});

2. 泛型服務(wù)注冊

services.AddTransient(typeof(IRepository<>), typeof(Repository<>));

3. 多實(shí)現(xiàn)解決方案

// 注冊多個(gè)實(shí)現(xiàn)
services.AddTransient<IMessageService, EmailService>();
services.AddTransient<IMessageService, SmsService>();

// 解析時(shí)獲取所有實(shí)現(xiàn)
var services = provider.GetServices<IMessageService>();

五、ASP.NET Core中的DI集成

1. 控制器注入

public class HomeController : Controller
{
    private readonly ILogger _logger;
    
    public HomeController(ILogger<HomeController> logger)
    {
        _logger = logger; // 自動(dòng)注入
    }
}

2. 視圖注入

@inject IConfiguration Config
<p>當(dāng)前環(huán)境: @Config["Environment"]</p>

3. 中間件注入

public class CustomMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger _logger;
    
    public CustomMiddleware(
        RequestDelegate next,
        ILogger<CustomMiddleware> logger)
    {
        _next = next;
        _logger = logger;
    }
    
    public async Task InvokeAsync(HttpContext context)
    {
        // 使用注入的服務(wù)
        _logger.LogInformation("中間件執(zhí)行");
        await _next(context);
    }
}

六、自定義DI容器實(shí)現(xiàn)

1. 簡易DI容器實(shí)現(xiàn)

public class SimpleContainer : IServiceProvider
{
    private readonly Dictionary<Type, ServiceDescriptor> _descriptors;
    
    public SimpleContainer(IEnumerable<ServiceDescriptor> descriptors)
    {
        _descriptors = descriptors.ToDictionary(x => x.ServiceType);
    }
    
    public object GetService(Type serviceType)
    {
        if (!_descriptors.TryGetValue(serviceType, out var descriptor))
            return null;
            
        if (descriptor.ImplementationInstance != null)
            return descriptor.ImplementationInstance;
            
        var type = descriptor.ImplementationType ?? descriptor.ServiceType;
        return ActivatorUtilities.CreateInstance(this, type);
    }
}

2. 屬性注入實(shí)現(xiàn)

public static class PropertyInjectionExtensions
{
    public static void AddPropertyInjection(this IServiceCollection services)
    {
        services.AddTransient<IStartupFilter, PropertyInjectionStartupFilter>();
    }
}

public class PropertyInjectionStartupFilter : IStartupFilter
{
    public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
    {
        return builder =>
        {
            builder.Use(async (context, nextMiddleware) =>
            {
                var endpoint = context.GetEndpoint();
                if (endpoint?.Metadata.GetMetadata<ControllerActionDescriptor>() is { } descriptor)
                {
                    var controller = context.RequestServices.GetRequiredService(descriptor.ControllerTypeInfo);
                    // 反射實(shí)現(xiàn)屬性注入
                    InjectProperties(controller, context.RequestServices);
                }
                await nextMiddleware();
            });
            next(builder);
        };
    }
    
    private void InjectProperties(object target, IServiceProvider services)
    {
        var properties = target.GetType().GetProperties()
            .Where(p => p.CanWrite && p.GetCustomAttribute<InjectAttribute>() != null);
            
        foreach (var prop in properties)
        {
            var service = services.GetService(prop.PropertyType);
            if (service != null)
                prop.SetValue(target, service);
        }
    }
}

七、最佳實(shí)踐

1. 服務(wù)設(shè)計(jì)原則

  • 遵循顯式依賴原則
  • 避免服務(wù)定位 器模式(反模式)
  • 保持服務(wù)輕量級(jí)

2. 常見陷阱

// 錯(cuò)誤示例:捕獲Scoped服務(wù)到Singleton中
services.AddSingleton<IBackgroundService>(provider => {
    var scopedService = provider.GetRequiredService<IScopedService>(); // 危險(xiǎn)!
    return new BackgroundService(scopedService);
});

// 正確做法:使用IServiceScopeFactory
services.AddSingleton<IBackgroundService>(provider => {
    var scopeFactory = provider.GetRequiredService<IServiceScopeFactory>();
    return new BackgroundService(scopeFactory);
});

八、性能優(yōu)化

1. 避免過度注入

// 不好:注入過多服務(wù)
public class OrderService(
    ILogger logger,
    IEmailService emailService,
    ISmsService smsService,
    IRepository repo,
    ICache cache,
    IConfig config)
{
    // ...
}

// 改進(jìn):使用聚合服務(wù)
public class OrderService(
    ILogger logger,
    INotificationService notification,
    IOrderInfrastructure infra)
{
    // ...
}

2. 編譯時(shí)注入

[RegisterTransient(typeof(IMyService))]
public class MyService : IMyService
{
    // ...
}

// 使用Source Generator自動(dòng)生成注冊代碼
static partial class ServiceRegistration
{
    static partial void AddGeneratedServices(IServiceCollection services)
    {
        services.AddTransient<IMyService, MyService>();
    }
}

.NET的依賴注入系統(tǒng)是框架的核心基礎(chǔ)設(shè)施,理解其原理和實(shí)現(xiàn)方式有助于編寫更可測試、更松耦合的應(yīng)用程序。

到此這篇關(guān)于全面解析.NET中的依賴注入(DI)的文章就介紹到這了,更多相關(guān).NET依賴注入DI內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

康平县| 昆明市| 吴忠市| 沙坪坝区| 察哈| 雷波县| 河池市| 宝清县| 江油市| 仲巴县| 阳西县| 钟祥市| 厦门市| 普洱| 平遥县| 多伦县| 大安市| 金堂县| 集贤县| 昌宁县| 东海县| 敖汉旗| 昂仁县| 新巴尔虎左旗| 定陶县| 瑞安市| 治多县| 临沂市| 沙河市| 阳信县| 涿鹿县| 平南县| 株洲县| 南平市| 双鸭山市| 遵化市| 平阳县| 南通市| 南岸区| 中宁县| 东乡族自治县|