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");
            }
        }
Example #5
0
        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));
 }
Example #12
0
        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);
            });
        }
Example #14
0
 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));
        }
Example #17
0
 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();
        }
Example #19
0
 public TransientCallSite(IService key, IServiceCallSite serviceCallSite)
 {
     Service         = key;
     ServiceCallSite = serviceCallSite;
 }
Example #20
0
        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));
 }
Example #22
0
 protected abstract Func <ServiceProviderEngineScope, object> RealizeService(IServiceCallSite callSite);
Example #23
0
        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;
 }
Example #25
0
 public void Add(Type type, IServiceCallSite serviceCallSite)
 {
     _callSiteCache[type] = serviceCallSite;
 }
 public TransientCallSite(IServiceCallSite serviceCallSite)
 {
     ServiceCallSite = serviceCallSite;
 }
Example #27
0
 private static object Invoke(IServiceCallSite callSite, ServiceProviderEngine provider)
 {
     return(CallSiteRuntimeResolver.Resolve(callSite, provider.Root));
 }
 public TransientCallSite(IServiceCallSite service)
 {
     _service = service;
 }
Example #29
0
 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);
 }
Example #32
0
 public ScopedCallSite(IServiceCallSite serviceCallSite, object cacheKey)
 {
     ServiceCallSite = serviceCallSite;
     CacheKey        = cacheKey;
 }
Example #33
0
 public object Resolve(IServiceCallSite callSite, ServiceProvider provider)
 {
     return(VisitCallSite(callSite, provider));
 }
Example #34
0
 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;
 }