欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-10-16 13:46:23
转载请注明出处: https://home.cnblogs.com/u/zhiyong-ITNote/ 常用扩展方法 注入依赖服务: new ServiceCollection().AddSingleton(); // ......

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

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

asp.net core 依赖注入实现全过程粗略剖析(1)
new ServiceCollection().AddSingleton<IApplicationBuilder, ApplicationBuilder>();
View Code

// AddSingleton多个重载方法 源码

asp.net core 依赖注入实现全过程粗略剖析(1)
public static IServiceCollection AddSingleton<TService, 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 : IList<ServiceDescriptor>
{}
View Code

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

我们看看ServiceProvider的源码:

asp.net core 依赖注入实现全过程粗略剖析(1)
 public sealed class ServiceProvider : IServiceProvider, IDisposable, IServiceProviderEngineCallback
    {
        private readonly IServiceProviderEngine _engine;

        private readonly CallSiteValidator _callSiteValidator;

        internal ServiceProvider(IEnumerable<ServiceDescriptor> 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);
        }
    }
View Code

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

asp.net core 依赖注入实现全过程粗略剖析(1)
/// <inheritdoc />
public ServiceLifetime Lifetime { get; }

/// <inheritdoc />
public Type ServiceType { get; }

/// <inheritdoc />
public Type ImplementationType { get; }

/// <inheritdoc />
public object ImplementationInstance { get; }

/// <inheritdoc />
public Func<IServiceProvider, object> ImplementationFactory { get; }
View Code

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

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

public object GetService(Type serviceType);

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

asp.net core 依赖注入实现全过程粗略剖析(1)
public sealed class ServiceProvider : IServiceProvider, IDisposable, IServiceProviderEngineCallback
{
private readonly IServiceProviderEngine _engine;

private readonly CallSiteValidator _callSiteValidator;

internal ServiceProvider(IEnumerable<ServiceDescriptor> 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);
}
}
View Code

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

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

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

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