.NET Core开发日志——依赖注入 (2)

假设注册是用的public static IServiceCollection AddSingleton(this IServiceCollection services, Type serviceType, Type implementationType)方法,那么之后的处理会生成一个SingletonCallSite对象并且包含ConstructorCallSite参数值。

private IServiceCallSite TryCreateExact(ServiceDescriptor descriptor, Type serviceType, CallSiteChain callSiteChain) { if (serviceType == descriptor.ServiceType) { IServiceCallSite callSite; if (descriptor.ImplementationInstance != null) { callSite = new ConstantCallSite(descriptor.ServiceType, descriptor.ImplementationInstance); } else if (descriptor.ImplementationFactory != null) { callSite = new FactoryCallSite(descriptor.ServiceType, descriptor.ImplementationFactory); } else if (descriptor.ImplementationType != null) { callSite = CreateConstructorCallSite(descriptor.ServiceType, descriptor.ImplementationType, callSiteChain); } else { throw new InvalidOperationException("Invalid service descriptor"); } return ApplyLifetime(callSite, descriptor, descriptor.Lifetime); } return null; } private IServiceCallSite CreateConstructorCallSite(Type serviceType, Type implementationType, CallSiteChain callSiteChain) { callSiteChain.Add(serviceType, implementationType); var constructors = implementationType.GetTypeInfo() .DeclaredConstructors .Where(constructor => constructor.IsPublic) .ToArray(); IServiceCallSite[] parameterCallSites = null; if (constructors.Length == 0) { throw new InvalidOperationException(Resources.FormatNoConstructorMatch(implementationType)); } else if (constructors.Length == 1) { var constructor = constructors[0]; var parameters = constructor.GetParameters(); if (parameters.Length == 0) { return new CreateInstanceCallSite(serviceType, implementationType); } parameterCallSites = CreateArgumentCallSites( serviceType, implementationType, callSiteChain, parameters, throwIfCallSiteNotFound: true); return new ConstructorCallSite(serviceType, constructor, parameterCallSites); } ... } private IServiceCallSite ApplyLifetime(IServiceCallSite serviceCallSite, object cacheKey, ServiceLifetime descriptorLifetime) { if (serviceCallSite is ConstantCallSite) { return serviceCallSite; } switch (descriptorLifetime) { case ServiceLifetime.Transient: return new TransientCallSite(serviceCallSite); case ServiceLifetime.Scoped: return new ScopedCallSite(serviceCallSite, cacheKey); case ServiceLifetime.Singleton: return new SingletonCallSite(serviceCallSite, cacheKey); default: throw new ArgumentOutOfRangeException(nameof(descriptorLifetime)); } }

ServiceProvider真正解析的是这个生成出来的CallSite对象。

protected override Func<ServiceProviderEngineScope, object> RealizeService(IServiceCallSite callSite) { var callCount = 0; return scope => { if (Interlocked.Increment(ref callCount) == 2) { Task.Run(() => base.RealizeService(callSite)); } return RuntimeResolver.Resolve(callSite, scope); }; } public object Resolve(IServiceCallSite callSite, ServiceProviderEngineScope scope) { return VisitCallSite(callSite, scope); } protected virtual TResult VisitCallSite(IServiceCallSite callSite, TArgument argument) { switch (callSite.Kind) { case CallSiteKind.Factory: return VisitFactory((FactoryCallSite)callSite, argument); case CallSiteKind.IEnumerable: return VisitIEnumerable((IEnumerableCallSite)callSite, argument); case CallSiteKind.Constructor: return VisitConstructor((ConstructorCallSite)callSite, argument); case CallSiteKind.Transient: return VisitTransient((TransientCallSite)callSite, argument); case CallSiteKind.Singleton: return VisitSingleton((SingletonCallSite)callSite, argument); case CallSiteKind.Scope: return VisitScoped((ScopedCallSite)callSite, argument); case CallSiteKind.Constant: return VisitConstant((ConstantCallSite)callSite, argument); case CallSiteKind.CreateInstance: return VisitCreateInstance((CreateInstanceCallSite)callSite, argument); case CallSiteKind.ServiceProvider: return VisitServiceProvider((ServiceProviderCallSite)callSite, argument); case CallSiteKind.ServiceScopeFactory: return VisitServiceScopeFactory((ServiceScopeFactoryCallSite)callSite, argument); default: throw new NotSupportedException($"Call site type {callSite.GetType()} is not supported"); } }

因为上例中CallSite的类型是Constructor,所以最终通过VisitConstructor方法获得所依赖的对象。

protected override object VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProviderEngineScope scope) { object[] parameterValues = new object[constructorCallSite.ParameterCallSites.Length]; for (var index = 0; index < parameterValues.Length; index++) { parameterValues[index] = VisitCallSite(constructorCallSite.ParameterCallSites[index], scope); } try { return constructorCallSite.ConstructorInfo.Invoke(parameterValues); } catch (Exception ex) when (ex.InnerException != null) { ExceptionDispatchInfo.Capture(ex.InnerException).Throw(); // The above line will always throw, but the compiler requires we throw explicitly. throw; } }

至于创建对象的方法是用反射,表达式树(Expression Tree)还是IL Emit,则取决于所使用的内部引擎。

释放

创建ServiceProviderEngine的时候会为其Root属性绑定ServiceProviderEngineScope类型的值,Root = new ServiceProviderEngineScope(this);。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zydzfw.html