/// <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)); }
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)); }
/// <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); }
/// <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); }
/// <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)); }
/// <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); }