/// <summary>
        /// Provide an expression that uses the lifestyle
        /// </summary>
        /// <param name="scope">scope for the strategy</param>
        /// <param name="request">activation request</param>
        /// <param name="activationExpression">expression to create strategy type</param>
        /// <returns></returns>
        public IActivationExpressionResult ProvideLifestyleExpression(IInjectionScope scope, IActivationExpressionRequest request, Func <IActivationExpressionRequest, IActivationExpressionResult> activationExpression)
        {
            if (CompiledDelegate == null)
            {
                // new request as we don't want to carry any info over from parent request
                var newRequest = request.NewRootedRequest(request.ActivationType, scope, true);

                var localDelegate = request.Services.Compiler.CompileDelegate(scope, activationExpression(newRequest));

                Interlocked.CompareExchange(ref CompiledDelegate, localDelegate, null);
            }

            var getValueFromScopeMethod =
                typeof(SingletonPerNamedScopeLifestyle).GetRuntimeMethod("GetValueFromScope",
                                                                         new[]
            {
                typeof(IExportLocatorScope),
                typeof(ActivationStrategyDelegate),
                typeof(string),
                typeof(string),
                typeof(StaticInjectionContext)
            });

            var closedMethod = getValueFromScopeMethod.MakeGenericMethod(request.ActivationType);

            var expression = Expression.Call(closedMethod,
                                             request.Constants.ScopeParameter,
                                             Expression.Constant(CompiledDelegate),
                                             Expression.Constant(UniqueId),
                                             Expression.Constant(_scopeName),
                                             Expression.Constant(request.GetStaticInjectionContext()));

            return(request.Services.Compiler.CreateNewResult(request, expression));
        }
예제 #2
0
        public IActivationExpressionResult ProvideLifestyleExpression(IInjectionScope scope,
                                                                      IActivationExpressionRequest request,
                                                                      Func <IActivationExpressionRequest, IActivationExpressionResult> activationExpression)
        {
            if (ConstantExpression != null)
            {
                return(request.Services.Compiler.CreateNewResult(request, ConstantExpression));
            }

            // Create new request as we shouldn't carry over anything from the previous request
            var newRequest = request.NewRootedRequest(request.ActivationType, scope, true);

            _activationDelegate =
                request.Services.Compiler.CompileDelegate(scope, activationExpression(newRequest));

            var singletonMethod = GetType().GetTypeInfo().GetDeclaredMethod("SingletonActivation");

            ConstantExpression = Expression.Call(Expression.Constant(this), singletonMethod,
                                                 request.Constants.ScopeParameter, request.Constants.RootDisposalScope,
                                                 request.Constants.InjectionContextParameter);

            ConstantExpression = Expression.Convert(ConstantExpression, request.ActivationType);

            return(request.Services.Compiler.CreateNewResult(request, ConstantExpression));
        }
예제 #3
0
        /// <summary>
        /// Provide an expression that uses the lifestyle
        /// </summary>
        /// <param name="scope">scope for the strategy</param>
        /// <param name="request">activation request</param>
        /// <param name="activationExpression">expression to create strategy type</param>
        /// <returns></returns>
        public virtual IActivationExpressionResult ProvideLifestyleExpression(IInjectionScope scope, IActivationExpressionRequest request, Func <IActivationExpressionRequest, IActivationExpressionResult> activationExpression)
        {
            var local = request.PerDelegateData.GetExtraDataOrDefaultValue <ParameterExpression>("local" + UniqueId);

            if (local != null)
            {
                return(request.Services.Compiler.CreateNewResult(request, local));
            }

            if (CompiledDelegate == null)
            {
                // new request as we don't want to carry any info over from parent request
                var newRequest = request.NewRootedRequest(request.ActivationType, scope, true);

                var localDelegate = request.Services.Compiler.CompileDelegate(scope, activationExpression(newRequest));

                Interlocked.CompareExchange(ref CompiledDelegate, localDelegate, null);
            }

            var getValueFromScopeMethod = typeof(SingletonPerScopeLifestyle).GetRuntimeMethod(ThreadSafe ? "GetValueFromScopeThreadSafe" : "GetValueFromScope", new[]
            {
                typeof(IExportLocatorScope),
                typeof(ActivationStrategyDelegate),
                typeof(string),
                typeof(bool),
                typeof(IInjectionContext)
            });

            var closedMethod = getValueFromScopeMethod.MakeGenericMethod(request.ActivationType);

            var expression = Expression.Call(closedMethod,
                                             request.ScopeParameter,
                                             Expression.Constant(CompiledDelegate),
                                             Expression.Constant(UniqueId),
                                             Expression.Constant(scope.ScopeConfiguration.SingletonPerScopeShareContext),
                                             request.InjectionContextParameter);

            local = Expression.Variable(request.ActivationType);

            request.PerDelegateData.SetExtraData("local" + UniqueId, local);

            var assignExpression = Expression.Assign(local, expression);

            var result = request.Services.Compiler.CreateNewResult(request, local);

            result.AddExtraParameter(local);
            result.AddExtraExpression(assignExpression);

            return(result);
        }
예제 #4
0
        /// <summary>
        /// Provide an expression that uses the lifestyle
        /// </summary>
        /// <param name="scope">scope for the strategy</param>
        /// <param name="request">activation request</param>
        /// <param name="activationExpression">expression to create strategy type</param>
        /// <returns></returns>
        public IActivationExpressionResult ProvideLifestyleExpression(IInjectionScope scope, IActivationExpressionRequest request, Func <IActivationExpressionRequest, IActivationExpressionResult> activationExpression)
        {
            if (_delegate == null)
            {
                // new request as we don't want to carry any info over from parent request
                var newRequest = request.NewRootedRequest(request.ActivationType, scope, true);

                var newDelegate = request.Services.Compiler.CompileDelegate(scope, activationExpression(newRequest));

                Interlocked.CompareExchange(ref _delegate, newDelegate, null);
            }

            var getMethod = typeof(WeakSingletonLifestyle).GetRuntimeMethod(nameof(GetValue), new[] { typeof(IInjectionScope) });

            var closedMethod = getMethod.MakeGenericMethod(request.ActivationType);

            var expression = Expression.Call(Expression.Constant(this), closedMethod, Expression.Constant(scope));

            return(request.Services.Compiler.CreateNewResult(request, expression));
        }
        public IActivationExpressionResult ProvideLifestyleExpression(IInjectionScope scope, IActivationExpressionRequest request,
                                                                      Func <IActivationExpressionRequest, IActivationExpressionResult> activationExpression)
        {
            request.RequireInjectionContext();

            if (ConstantExpression != null)
            {
                return(request.Services.Compiler.CreateNewResult(request, ConstantExpression));
            }

            // Create new request as we shouldn't carry over anything from the previous request
            var newRequest = request.NewRootedRequest(request.ActivationType, scope, true);

            _activationDelegate = request.Services.Compiler.CompileDelegate(scope, activationExpression(newRequest));

            ConstantExpression = Expression.Convert(Expression.Call(Expression.Constant(this), getInstanceMethodInfo,
                                                                    newRequest.ScopeParameter, Expression.Constant(scope), request.InjectionContextParameter,
                                                                    Expression.Constant(_activationDelegate)), request.ActivationType);

            var result = request.Services.Compiler.CreateNewResult(request, ConstantExpression);

            return(result);
        }
예제 #6
0
        /// <summary>
        /// Provide an expression that uses the lifestyle
        /// </summary>
        /// <param name="scope">scope for the strategy</param>
        /// <param name="request">activation request</param>
        /// <param name="activationExpression">expression to create strategy type</param>
        /// <returns></returns>
        public virtual IActivationExpressionResult ProvideLifestyleExpression(IInjectionScope scope, IActivationExpressionRequest request, Func <IActivationExpressionRequest, IActivationExpressionResult> activationExpression)
        {
            if (ConstantExpression != null)
            {
                return(request.Services.Compiler.CreateNewResult(request, ConstantExpression));
            }

            // Create new request as we shouldn't carry over anything from the previous request
            var newRequest = request.NewRootedRequest(request.ActivationType, scope, true);

            _activationDelegate = request.Services.Compiler.CompileDelegate(scope, activationExpression(newRequest));

            lock (_lockObject)
            {
                if (_singleton == null)
                {
                    _singleton = _activationDelegate(scope, scope, null);
                }
            }

            Interlocked.CompareExchange(ref ConstantExpression, Expression.Constant(_singleton), null);

            return(request.Services.Compiler.CreateNewResult(request, ConstantExpression));
        }
예제 #7
0
        /// <summary>
        /// Provide an expression that uses the lifestyle
        /// </summary>
        /// <param name="scope">scope for the strategy</param>
        /// <param name="request">activation request</param>
        /// <param name="activationExpression">expression to create strategy type</param>
        /// <returns></returns>
        public virtual IActivationExpressionResult ProvideLifestyleExpression(IInjectionScope scope, IActivationExpressionRequest request, Func <IActivationExpressionRequest, IActivationExpressionResult> activationExpression)
        {
            var local = request.PerDelegateData.GetExtraDataOrDefaultValue <ParameterExpression>("local" + UniqueId);

            if (local != null)
            {
                return(request.Services.Compiler.CreateNewResult(request, local));
            }

            request.RequireExportScope();

            if (CompiledDelegate == null)
            {
                // new request as we don't want to carry any info over from parent request
                var newRequest = request.NewRootedRequest(request.ActivationType, scope, true);

                var newResult = activationExpression(newRequest);

                Delegate localDelegate = null;

                if (ThreadSafe || newRequest.ExportScopeRequired() || newRequest.DisposalScopeRequired() ||
                    newRequest.InjectionContextRequired())
                {
                    localDelegate = request.Services.Compiler.CompileDelegate(scope, newResult);
                }
                else
                {
                    var openMethod = GetType().GetTypeInfo().GetDeclaredMethod(nameof(CompileFuncDelage));

                    var closed = openMethod.MakeGenericMethod(newResult.Expression.Type);

                    localDelegate = (Delegate)closed.Invoke(null, new object[] { request, scope, newResult });
                }

                Interlocked.CompareExchange(ref CompiledDelegate, localDelegate, null);
            }

            Expression createExpression;

            if (ThreadSafe)
            {
                var getValueFromScopeMethod = typeof(SingletonPerScopeLifestyle).GetRuntimeMethod(nameof(GetValueFromScopeThreadSafe), new[]
                {
                    typeof(IExportLocatorScope),
                    typeof(ActivationStrategyDelegate),
                    typeof(string),
                    typeof(bool),
                    typeof(IInjectionContext)
                });

                var closedMethod = getValueFromScopeMethod.MakeGenericMethod(request.ActivationType);

                createExpression = Expression.Call(closedMethod,
                                                   request.ScopeParameter,
                                                   Expression.Constant(CompiledDelegate),
                                                   Expression.Constant(UniqueId),
                                                   Expression.Constant(scope.ScopeConfiguration.SingletonPerScopeShareContext),
                                                   request.InjectionContextParameter);
            }
            else
            {
                var invokeMethodFastLane = CompiledDelegate.GetMethodInfo().GetParameters().Length < 3;

                if (invokeMethodFastLane)
                {
                    var getOrCreateMethod = typeof(IExportLocatorScope).GetTypeInfo()
                                            .GetDeclaredMethods(nameof(IExportLocatorScope.GetOrCreateScopedService)).First(m => m.GetParameters().Length == 2);

                    var closedMethod = getOrCreateMethod.MakeGenericMethod(request.ActivationType);

                    createExpression = Expression.Call(request.ScopeParameter, closedMethod,
                                                       Expression.Constant(UniqueIntIdValue), Expression.Constant(CompiledDelegate));
                }
                else
                {
                    var getOrCreateMethod = typeof(IExportLocatorScope).GetRuntimeMethod(nameof(IExportLocatorScope.GetOrCreateScopedService),
                                                                                         new[] { typeof(int), typeof(ActivationStrategyDelegate), typeof(IInjectionContext) });

                    var closedMethod = getOrCreateMethod.MakeGenericMethod(request.ActivationType);

                    createExpression = Expression.Call(request.ScopeParameter, closedMethod,
                                                       Expression.Constant(UniqueIntIdValue), Expression.Constant(CompiledDelegate),
                                                       request.InjectionContextParameter);
                }
            }

            local = Expression.Variable(request.ActivationType);

            request.PerDelegateData.SetExtraData("local" + UniqueId, local);

            var assignExpression = Expression.Assign(local, createExpression);

            var result = request.Services.Compiler.CreateNewResult(request, local);

            result.AddExtraParameter(local);
            result.AddExtraExpression(assignExpression);

            return(result);
        }