public IServiceCallSite CreateCallSite(ServiceProvider provider, ISet<Type> callSiteChain) { ConstructorInfo[] constructors = _descriptor.ImplementationType.GetTypeInfo() .DeclaredConstructors .Where(IsInjectable) .ToArray(); // TODO: actual service-fulfillment constructor selection if (constructors.Length == 1) { ParameterInfo[] parameters = constructors[0].GetParameters(); IServiceCallSite[] parameterCallSites = new IServiceCallSite[parameters.Length]; for (var index = 0; index != parameters.Length; ++index) { parameterCallSites[index] = provider.GetServiceCallSite(parameters[index].ParameterType, callSiteChain); if (parameterCallSites[index] == null && parameters[index].HasDefaultValue) { parameterCallSites[index] = new ConstantCallSite(parameters[index].DefaultValue); } if (parameterCallSites[index] == null) { throw new InvalidOperationException(Resources.FormatCannotResolveService( parameters[index].ParameterType, _descriptor.ImplementationType)); } } return new ConstructorCallSite(constructors[0], parameterCallSites); } return new CreateInstanceCallSite(_descriptor); }
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)); } }
private Expression <Func <ServiceProvider, object> > BuildExpression(IServiceCallSite callSite) { var serviceExpression = VisitCallSite(callSite, ProviderParameter); var body = new List <Expression>(); if (_requiresResolvedServices) { body.Add(ResolvedServicesVariableAssignment); serviceExpression = Lock(serviceExpression, ResolvedServices); } body.Add(serviceExpression); var variables = _requiresResolvedServices ? new[] { ResolvedServices } : Enumerable.Empty <ParameterExpression>(); return(Expression.Lambda <Func <ServiceProvider, object> >( Expression.Block(variables, body), ProviderParameter)); }
protected virtual TResult VisitCallSite(IServiceCallSite callSite, TArgument argument) { switch (callSite) { case FactoryCallSite factoryCallSite: return(VisitFactory(factoryCallSite, argument)); case IEnumerableCallSite enumerableCallSite: return(VisitIEnumerable(enumerableCallSite, argument)); case ConstructorCallSite constructorCallSite: return(VisitConstructor(constructorCallSite, argument)); case TransientCallSite transientCallSite: return(VisitTransient(transientCallSite, argument)); case SingletonCallSite singletonCallSite: return(VisitSingleton(singletonCallSite, argument)); case ScopedCallSite scopedCallSite: return(VisitScoped(scopedCallSite, argument)); case ConstantCallSite constantCallSite: return(VisitConstant(constantCallSite, argument)); case CreateInstanceCallSite createInstanceCallSite: return(VisitCreateInstance(createInstanceCallSite, argument)); case ServiceProviderCallSite serviceProviderCallSite: return(VisitServiceProvider(serviceProviderCallSite, argument)); case ServiceScopeFactoryCallSite scopeFactoryCallSite: return(VisitServiceScopeFactory(scopeFactoryCallSite, argument)); default: throw new NotSupportedException($"Call site type {callSite.GetType()} is not supported"); } }
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"); } }
public IServiceCallSite CreateCallSite(ServiceProvider provider, ISet <Type> callSiteChain) { IServiceCallSite serviceCallSite = (null != this.ServiceDescriptor.ImplementationInstance) ? new InstanceCallSite(this.ServiceDescriptor.ImplementationInstance) : null; serviceCallSite = serviceCallSite ?? ((null != this.ServiceDescriptor.ImplementationFactory) ? new FactoryCallSite(this.ServiceDescriptor.ImplementationFactory) : null); serviceCallSite = serviceCallSite ?? this.CreateConstructorCallSite(provider, callSiteChain); switch (this.Lifetime) { case ServiceLifetime.Transient: return(new TransientCallSite(serviceCallSite)); case ServiceLifetime.Scoped: return(new ScopedCallSite(this, serviceCallSite)); default: return(new SingletonCallSite(this, serviceCallSite)); } }
internal IServiceCallSite GetResolveCallSite(IService service, ISet <Type> callSiteChain) { IServiceCallSite serviceCallSite = service.CreateCallSite(this, callSiteChain); // Instance services do not need caching/disposing if (serviceCallSite is InstanceService) { return(serviceCallSite); } if (service.Lifetime == ServiceLifetime.Transient) { return(new TransientCallSite(serviceCallSite)); } else if (service.Lifetime == ServiceLifetime.Scoped) { return(new ScopedCallSite(service, serviceCallSite)); } else { return(new SingletonCallSite(service, serviceCallSite)); } }
internal static Func <ServiceProvider, object> RealizeService(ServiceTable table, Type serviceType, IServiceCallSite callSite) { var callCount = 0; return(provider => { if (Interlocked.Increment(ref callCount) == 2) { Task.Run(() => { var providerExpression = Expression.Parameter(typeof(ServiceProvider), "provider"); var lambdaExpression = Expression.Lambda <Func <ServiceProvider, object> >( callSite.Build(providerExpression), providerExpression); table.RealizedServices[serviceType] = lambdaExpression.Compile(); }); } return callSite.Invoke(provider); }); }
public CallSite(Type itemType, IServiceCallSite[] serviceCallSites) { _itemType = itemType; _serviceCallSites = serviceCallSites; }
public ScopedCallSite(IService key, IServiceCallSite serviceCallSite) { _key = key; _serviceCallSite = serviceCallSite; }
public object Resolve(IServiceCallSite callSite, ServiceProviderEngineScope scope) { return(VisitCallSite(callSite, scope)); }
private ILEmitResolverBuilderRuntimeContext GenerateMethodBody(IServiceCallSite callSite, ILGenerator generator, ILEmitCallSiteAnalysisResult info) { var context = new ILEmitResolverBuilderContext() { Generator = generator, Constants = null, Factories = null }; // try // { // Monitor.Enter(scope.ResolvedServices, out var lockTaken); // return [ create value ] // } // finally // { // if (lockTaken) Monitor.Exit(scope.ResolvedServices); // } var hasScopes = info.HasScope; if (hasScopes) { // Has to be first local defined var resolvedServicesLocal = context.Generator.DeclareLocal(typeof(IDictionary <object, object>)); Debug.Assert(resolvedServicesLocal.LocalIndex == 0); var lockTakenLocal = context.Generator.DeclareLocal(typeof(bool)); Debug.Assert(lockTakenLocal.LocalIndex == 1); context.Generator.BeginExceptionBlock(); // scope context.Generator.Emit(OpCodes.Ldarg_1); // .ResolvedServices context.Generator.Emit(OpCodes.Callvirt, ResolvedServicesGetter); context.Generator.Emit(OpCodes.Dup); // Store resolved services context.Generator.Emit(OpCodes.Stloc_0); context.Generator.Emit(OpCodes.Ldloca_S, 1); // Monitor.Enter context.Generator.Emit(OpCodes.Call, ExpressionResolverBuilder.MonitorEnterMethodInfo); } VisitCallSite(callSite, context); if (hasScopes) { var resultLocal = context.Generator.DeclareLocal(typeof(object)); Stloc(context.Generator, resultLocal.LocalIndex); context.Generator.BeginFinallyBlock(); var postExitLabel = context.Generator.DefineLabel(); context.Generator.Emit(OpCodes.Ldloc_1); context.Generator.Emit(OpCodes.Brfalse, postExitLabel); context.Generator.Emit(OpCodes.Ldloc, 0); // Monitor.Exit context.Generator.Emit(OpCodes.Call, ExpressionResolverBuilder.MonitorExitMethodInfo); context.Generator.MarkLabel(postExitLabel); context.Generator.EndExceptionBlock(); Ldloc(context.Generator, resultLocal.LocalIndex); } context.Generator.Emit(OpCodes.Ret); return(new ILEmitResolverBuilderRuntimeContext { Constants = context.Constants?.ToArray(), Factories = context.Factories?.ToArray(), Root = _rootScope, RuntimeResolver = _runtimeResolver, ScopeFactory = _serviceScopeFactory }); }
internal static Func <ServiceProvider, object> RealizeService(Type serviceType, IServiceCallSite callSite) { var callCount = 0; return(provider => { if (Interlocked.Increment(ref callCount) == 2) { Task.Run(() => { var realizedService = new CallSiteExpressionBuilder(_callSiteRuntimeResolver) .Build(callSite); provider.RealizedServices[serviceType] = realizedService; }); } return _callSiteRuntimeResolver.Resolve(callSite, provider); }); }
public SingletonCallSite(IService service, IServiceCallSite serviceCallSite) : base(service, serviceCallSite) { }
public ILEmitCallSiteAnalysisResult CollectGenerationInfo(IServiceCallSite callSite) => VisitCallSite(callSite, null);
private Expression <Func <ServiceProviderEngineScope, object> > BuildExpression(IServiceCallSite callSite) { var context = new CallSiteExpressionBuilderContext { ScopeParameter = ScopeParameter }; var serviceExpression = VisitCallSite(callSite, context); if (context.RequiresResolvedServices) { return(Expression.Lambda <Func <ServiceProviderEngineScope, object> >( Expression.Block( new [] { ResolvedServices }, ResolvedServicesVariableAssignment, Lock(serviceExpression, ResolvedServices)), ScopeParameter)); } return(Expression.Lambda <Func <ServiceProviderEngineScope, object> >(serviceExpression, ScopeParameter)); }
public SingletonCallSite(IServiceCallSite serviceCallSite, object cacheKey) : base(serviceCallSite, cacheKey) { }
private static Func<ServiceProvider, object> CompileCallSite(IServiceCallSite callSite) { var providerExpression = Expression.Parameter(typeof(ServiceProvider), "provider"); var lambdaExpression = Expression.Lambda<Func<ServiceProvider, object>>( callSite.Build(providerExpression), providerExpression); return lambdaExpression.Compile(); }
public TransientCallSite(IService key, IServiceCallSite serviceCallSite) { Service = key; ServiceCallSite = serviceCallSite; }
private IServiceCallSite[] PopulateCallSites( ServiceProvider provider, ISet<Type> callSiteChain, ParameterInfo[] parameters, bool throwIfCallSiteNotFound) { var parameterCallSites = new IServiceCallSite[parameters.Length]; for (var index = 0; index < parameters.Length; index++) { var callSite = provider.GetServiceCallSite(parameters[index].ParameterType, callSiteChain); if (callSite == null && parameters[index].HasDefaultValue) { callSite = new ConstantCallSite(parameters[index].DefaultValue); } if (callSite == null) { if (throwIfCallSiteNotFound) { throw new InvalidOperationException(Resources.FormatCannotResolveService( parameters[index].ParameterType, _descriptor.ImplementationType)); } return null; } parameterCallSites[index] = callSite; } return parameterCallSites; }
private static Func <ServiceProvider, object> CompileCallSite(IServiceCallSite callSite) { return(new CallSiteExpressionBuilder(CallSiteRuntimeResolver).Build(callSite)); }
protected abstract Func <ServiceProviderEngineScope, object> RealizeService(IServiceCallSite callSite);
protected virtual TResult VisitCallSite(IServiceCallSite callSite, TArgument argument) { var factoryService = callSite as FactoryService; if (factoryService != null) { return(VisitFactoryService(factoryService, argument)); } var closedIEnumerableCallSite = callSite as ClosedIEnumerableCallSite; if (closedIEnumerableCallSite != null) { return(VisitClosedIEnumerable(closedIEnumerableCallSite, argument)); } var constructorCallSite = callSite as ConstructorCallSite; if (constructorCallSite != null) { return(VisitConstructor(constructorCallSite, argument)); } var transientCallSite = callSite as TransientCallSite; if (transientCallSite != null) { return(VisitTransient(transientCallSite, argument)); } var singletonCallSite = callSite as SingletonCallSite; if (singletonCallSite != null) { return(VisitSingleton(singletonCallSite, argument)); } var scopedCallSite = callSite as ScopedCallSite; if (scopedCallSite != null) { return(VisitScoped(scopedCallSite, argument)); } var constantCallSite = callSite as ConstantCallSite; if (constantCallSite != null) { return(VisitConstant(constantCallSite, argument)); } var createInstanceCallSite = callSite as CreateInstanceCallSite; if (createInstanceCallSite != null) { return(VisitCreateInstance(createInstanceCallSite, argument)); } var instanceCallSite = callSite as InstanceService; if (instanceCallSite != null) { return(VisitInstanceService(instanceCallSite, argument)); } var serviceProviderService = callSite as ServiceProviderService; if (serviceProviderService != null) { return(VisitServiceProviderService(serviceProviderService, argument)); } var emptyIEnumerableCallSite = callSite as EmptyIEnumerableCallSite; if (emptyIEnumerableCallSite != null) { return(VisitEmptyIEnumerable(emptyIEnumerableCallSite, argument)); } var serviceScopeService = callSite as ServiceScopeService; if (serviceScopeService != null) { return(VisitServiceScopeService(serviceScopeService, argument)); } throw new NotSupportedException($"调用点{callSite.GetType()} 不被支持。"); }
public ConstructorCallSite(ConstructorInfo constructorInfo, IServiceCallSite[] parameterCallSites) { _constructorInfo = constructorInfo; _parameterCallSites = parameterCallSites; }
public void Add(Type type, IServiceCallSite serviceCallSite) { _callSiteCache[type] = serviceCallSite; }
public TransientCallSite(IServiceCallSite serviceCallSite) { ServiceCallSite = serviceCallSite; }
private static object Invoke(IServiceCallSite callSite, ServiceProviderEngine provider) { return(CallSiteRuntimeResolver.Resolve(callSite, provider.Root)); }
public TransientCallSite(IServiceCallSite service) { _service = service; }
private static Func <ServiceProviderEngineScope, object> CompileCallSite(IServiceCallSite callSite, ServiceProviderEngine engine) { return(new ExpressionResolverBuilder(CallSiteRuntimeResolver, engine, engine.Root).Build(callSite)); }
public SingletonCallSite(IService key, IServiceCallSite serviceCallSite) : base(key, serviceCallSite) { }
void IServiceProviderEngineCallback.OnCreate(IServiceCallSite callSite) { _callSiteValidator.ValidateCallSite(callSite); }
public ScopedCallSite(IServiceCallSite serviceCallSite, object cacheKey) { ServiceCallSite = serviceCallSite; CacheKey = cacheKey; }
public object Resolve(IServiceCallSite callSite, ServiceProvider provider) { return(VisitCallSite(callSite, provider)); }
public IntercepCallSite(IProxyFactory proxyFactory, IServiceCallSite targetCallSite, Type serviceType) { this.ProxyFactory = proxyFactory; this.TargetCallSite = targetCallSite; this.ServiceType = serviceType; }
public ScopedCallSite(IService service, IServiceCallSite serviceCallSite) { this.Service = service; this.ServiceCallSite = serviceCallSite; }