首页后端开发ASP.NETasp.net core 依赖注入实现全过程粗略剖析(1)

asp.net core 依赖注入实现全过程粗略剖析(1)

时间2023-12-03 03:08:03发布访客分类ASP.NET浏览1164
导读:转载请注明出处: https://home.cnblogs.com/u/zhiyong-ITNote/常用扩展方法 注入依赖服务:new ServiceCollection( .AddSingleton<IApplicationBui...

转载请注明出处: https://home.cnblogs.com/u/zhiyong-ITNote/

常用扩展方法 注入依赖服务:

new ServiceCollection().AddSingletonIApplicationBuilder, ApplicationBuilder>
    ();
    

// AddSingleton多个重载方法 源码

public static IServiceCollection AddSingletonTService, TImplementation>
(this IServiceCollection services)
where TService : class
where TImplementation : class, TService
{

if (services == null)
{
    
throw new ArgumentNullException(nameof(services));

}
    

return services.AddSingleton(typeof(TService), typeof(TImplementation));

}


// Singleton模式 最终的调用
public static IServiceCollection AddSingleton(
this IServiceCollection services,
Type serviceType,
Type implementationType)
{

if (services == null)
{
    
throw new ArgumentNullException(nameof(services));

}


if (serviceType == null)
{
    
throw new ArgumentNullException(nameof(serviceType));

}


if (implementationType == null)
{
    
throw new ArgumentNullException(nameof(implementationType));

}
    

return Add(services, serviceType, implementationType, ServiceLifetime.Singleton);

}


// 所有的Addxxx 最终都是调用Add方法,将ServiceDescriptor添加到IServiceCollection中:
private static IServiceCollection Add(
IServiceCollection collection,
Type serviceType,
Type implementationType,
ServiceLifetime lifetime)
{
    
var descriptor = new ServiceDescriptor(serviceType, implementationType, lifetime);
    
collection.Add(descriptor);
    
return collection;

}
    

// IServiceCollection源码:
public interface IServiceCollection : IListServiceDescriptor>

{
}

如上,我们一般在ConfigureService中使用Addxxx将服务注入框架的过程。大概做个总结,其实就是屌用IServiceCollection的Addxxx 扩展方法,随后调用Add方法,初始化一个ServiceDescriptor,参数是我们注入的接口和类,还有就是生命周期。随后添加到IServiceCollection中,根据该接口的定义就是一个ServiceDescriptor的集合。

我们看看ServiceDescriptor的源码:

public ServiceDescriptor( 
 Type serviceType, 
 object instance) 
 : this(serviceType, ServiceLifetime.Singleton) 
{
 
 if (serviceType == null) 
 {
     
 throw new ArgumentNullException(nameof(serviceType));
 
 }
 
 
 if (instance == null) 
 {
     
 throw new ArgumentNullException(nameof(instance));
 
 }
     
 
 ImplementationInstance = instance;
 
}
    

该类就是初始化并获取如下属性:

/// inheritdoc />

public ServiceLifetime Lifetime {
     get;
 }
    

/// inheritdoc />

public Type ServiceType {
     get;
 }
    

/// inheritdoc />

public Type ImplementationType {
     get;
 }
    

/// inheritdoc />

public object ImplementationInstance {
     get;
 }
    

/// inheritdoc />
    
public FuncIServiceProvider, object>
 ImplementationFactory {
     get;
 }
    

到此,我们的服务注入到asp.net core框架中就完事了,那么服务的实例化呢?

首先我们理下思路,IServiceProvider接口对应的实现是ServiceProvider,这个类就是实例化了IServiceProvider接口,而IServiceProvider接口只有一个方法:

public object GetService(Type serviceType);

该方法就是获取注入的服务。但是ServiceProvider类不单单是获取注入的服务,服务的实例化还是在该类中实现的,我们看下:

public sealed class ServiceProvider : IServiceProvider, IDisposable, IServiceProviderEngineCallback
{
    
private readonly IServiceProviderEngine _engine;
    

private readonly CallSiteValidator _callSiteValidator;
    

internal ServiceProvider(IEnumerableServiceDescriptor>
 serviceDescriptors, ServiceProviderOptions options)
{
    
IServiceProviderEngineCallback callback = null;

if (options.ValidateScopes)
{
    
callback = this;
    
_callSiteValidator = new CallSiteValidator();

}

switch (options.Mode)
{
    
case ServiceProviderMode.Dynamic:
_engine = new DynamicServiceProviderEngine(serviceDescriptors, callback);
    
break;
    
case ServiceProviderMode.Runtime:
_engine = new RuntimeServiceProviderEngine(serviceDescriptors, callback);
    
break;
    
#if IL_EMIT
case ServiceProviderMode.ILEmit:
_engine = new ILEmitServiceProviderEngine(serviceDescriptors, callback);
    
break;
    
#endif
case ServiceProviderMode.Expressions:
_engine = new ExpressionsServiceProviderEngine(serviceDescriptors, callback);
    
break;
    
default:
throw new NotSupportedException(nameof(options.Mode));

}

}
    

/// summary>
    
/// Gets the service object of the specified type.
/// /summary>
    
/// param name="serviceType">
    /param>
    
/// returns>
    /returns>
    
public object GetService(Type serviceType) =>
     _engine.GetService(serviceType);
    

/// inheritdoc />
    
public void Dispose() =>
     _engine.Dispose();


void IServiceProviderEngineCallback.OnCreate(IServiceCallSite callSite)
{
    
_callSiteValidator.ValidateCallSite(callSite);

}


void IServiceProviderEngineCallback.OnResolve(Type serviceType, IServiceScope scope)
{
    
_callSiteValidator.ValidateResolution(serviceType, scope, _engine.RootScope);

}

}
    

可以看到该类的构造函数中就是实例化服务的过程了。很直白的可以看出我们常见的几种方法来实例化类:反射,Emit,表达式树等...

目前也算是交代清楚了相关的类。那么框架具体是如何来实例化的呢?整个的流程是怎么样的。篇2再叙

源码地址:https://github.com/aspnet/DependencyInjection  

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!


若转载请注明出处: asp.net core 依赖注入实现全过程粗略剖析(1)
本文地址: https://pptw.com/jishu/565631.html
asp.net core 依赖注入实现全过程粗略剖析(2) asp.net core 依赖注入实现全过程粗略剖析(3)

游客 回复需填写必要信息