private ActivationStrategyDelegate CompileDelegate() { lock (_lock) { if (_delegate == null) { var requestType = _request.ActivationType.GenericTypeArguments[0]; var newRequest = _request.NewRequest(requestType, _activationStrategy, typeof(Lazy <TResult>), RequestType.Other, null, true, true); newRequest.DisposalScopeExpression = _request.Constants.RootDisposalScope; var activationExpression = _request.Services.ExpressionBuilder.GetActivationExpression(_scope, newRequest); _delegate = _request.Services.Compiler.CompileDelegate(_scope, activationExpression); _scope = null; _request = null; _activationStrategy = null; } } return(_delegate); }
/// <summary> /// Default constructor /// </summary> /// <param name="scope"></param> /// <param name="context"></param> /// <param name="activationDelegate"></param> /// <param name="scopeName"></param> public Scoped(IExportLocatorScope scope, IInjectionContext context, ActivationStrategyDelegate activationDelegate, string scopeName = null) { _scope = scope; _context = context; _activationDelegate = activationDelegate; _scopeName = scopeName; }
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> /// try to create delegate using IL generation /// </summary> /// <param name="expressionContext">expression context</param> /// <param name="finalExpression">final expression to convert</param> /// <param name="newDelegate">created delegate</param> /// <returns>true if delegate was created</returns> public virtual bool TryCreateDelegate(IActivationExpressionResult expressionContext, Expression finalExpression, out ActivationStrategyDelegate newDelegate) { newDelegate = null; try { var request = new DynamicMethodGenerationRequest(expressionContext, TryGenerateIL); var constants = new List <object>(); if (!ImplementationFactory.Locate <IConstantExpressionCollector>().GetConstantExpressions(finalExpression, constants)) { return(false); } request.Constants = constants; var target = ImplementationFactory.Locate <IDynamicMethodTargetCreator>().CreateMethodTarget(request); if (target == null) { return(false); } request.Target = target; var method = new DynamicMethod(string.Empty, typeof(object), new[] { target.GetType(), typeof(IExportLocatorScope), typeof(IDisposalScope), typeof(IInjectionContext) }, target.GetType(), true); request.ILGenerator = method.GetILGenerator(); if (!TryGenerateIL(request, finalExpression)) { return(false); } request.ILGenerator.Emit(OpCodes.Ret); newDelegate = (ActivationStrategyDelegate)method.CreateDelegate(typeof(ActivationStrategyDelegate), target); return(true); } catch (Exception) { // ignore exception and compile linq expression normally } return(false); }
/// <summary> /// Default constructor /// </summary> /// <param name="scope"></param> /// <param name="disposalScope"></param> /// <param name="context"></param> /// <param name="action"></param> /// <param name="injectionContextCreator"></param> public FuncClass(IExportLocatorScope scope, IDisposalScope disposalScope, IInjectionContext context, ActivationStrategyDelegate action, IInjectionContextCreator injectionContextCreator) { _scope = scope; _disposalScope = disposalScope; _context = context; _action = action; _injectionContextCreator = injectionContextCreator; }
private ActivationStrategyDelegate AddObjectFactory(Type type, ActivationStrategyDelegate activationStrategyDelegate) { var hashCode = type.GetHashCode(); return(ImmutableHashTree.ThreadSafeAdd(ref ActivationDelegates[hashCode & ArrayLengthMinusOne], type, activationStrategyDelegate)); }
/// <summary> /// Add delegate to cache /// </summary> /// <param name="type"></param> /// <param name="activationStrategyDelegate"></param> public void AddDelegate(Type type, ActivationStrategyDelegate activationStrategyDelegate) { var hashCode = type.GetHashCode(); ImmutableHashTree.ThreadSafeAdd(ref _activationDelegates[hashCode & _activationDelegatesLengthMinusOne], type, activationStrategyDelegate); }
/// <summary> /// Default constructor /// </summary> /// <param name="scope"></param> /// <param name="request"></param> /// <param name="activationStrategy"></param> public FuncExpression(IInjectionScope scope, IActivationExpressionRequest request, IActivationStrategy activationStrategy) { var requestType = request.ActivationType.GenericTypeArguments[0]; var newRequest = request.NewRequest(requestType, activationStrategy, typeof(Func <TResult>), RequestType.Other, null, true); newRequest.DisposalScopeExpression = request.Constants.RootDisposalScope; var activationExpression = request.Services.ExpressionBuilder.GetActivationExpression(scope, newRequest); _action = request.Services.Compiler.CompileDelegate(scope, activationExpression); }
/// <summary> /// Default constructor /// </summary> /// <param name="scope"></param> /// <param name="disposalScope"></param> /// <param name="context"></param> /// <param name="action"></param> /// <param name="injectionContextCreator"></param> /// <param name="arg1Id"></param> /// <param name="arg2Id"></param> /// <param name="arg3Id"></param> /// <param name="arg4Id"></param> public FuncClass(IExportLocatorScope scope, IDisposalScope disposalScope, IInjectionContext context, ActivationStrategyDelegate action, IInjectionContextCreator injectionContextCreator, string arg1Id, string arg2Id, string arg3Id, string arg4Id) { _scope = scope; _disposalScope = disposalScope; _context = context; _action = action; _injectionContextCreator = injectionContextCreator; _arg1Id = arg1Id; _arg2Id = arg2Id; _arg3Id = arg3Id; _arg4Id = arg4Id; }
/// <summary> /// Create lazy instance /// </summary> /// <param name="scope"></param> /// <param name="disposalScope"></param> /// <param name="injectionContext"></param> /// <returns></returns> public Lazy <TResult> CreateLazy(IExportLocatorScope scope, IDisposalScope disposalScope, IInjectionContext injectionContext) { return(new Lazy <TResult>(() => { if (_delegate == null) { _delegate = CompileDelegate(); } return (TResult)_delegate(scope, disposalScope, injectionContext); })); }
/// <summary> /// Create lazy instance /// </summary> /// <param name="scope"></param> /// <param name="disposalScope"></param> /// <param name="injectionContext"></param> /// <returns></returns> public Lazy <TResult, IActivationStrategyMetadata> CreateLazy(IExportLocatorScope scope, IDisposalScope disposalScope, IInjectionContext injectionContext) { return(new Lazy <TResult, IActivationStrategyMetadata>(() => { if (_delegate == null) { _delegate = CompileDelegate(); } return (TResult)_delegate(scope, disposalScope, injectionContext); }, _metadata)); }
public void DynamicTypeBuilder_NoParams(DynamicTypeBuilder builder, IExportLocatorScope scope, IDisposalScope disposalScope, IInjectionContext context) { var proxyType = builder.CreateType(typeof(IBasicServiceProvider), out List <DynamicTypeBuilder.DelegateInfo> methods); var newBasicService = new BasicService(); var func = new ActivationStrategyDelegate((s, d, c) => newBasicService); var instance = (IBasicServiceProvider)Activator.CreateInstance(proxyType, scope, disposalScope, context, func); var basicService = instance.CreateBasicService(); Assert.NotNull(basicService); Assert.Same(newBasicService, basicService); }
/// <summary> /// Compiles an expression result to a delegate /// </summary> /// <param name="expressionContext"></param> /// <param name="parameters"></param> /// <param name="extraExpressions"></param> /// <param name="finalExpression"></param> /// <returns></returns> protected override ActivationStrategyDelegate CompileExpressionResultToDelegate(IActivationExpressionResult expressionContext, ParameterExpression[] parameters, Expression[] extraExpressions, Expression finalExpression) { ActivationStrategyDelegate dynamicDelegate = (ActivationStrategyDelegate)_linqToDynamicMethodConverter.TryCreateDelegate(expressionContext, parameters, extraExpressions, finalExpression, typeof(ActivationStrategyDelegate)); if (dynamicDelegate != null) { return(dynamicDelegate); } expressionContext.Request.RequestingScope.ScopeConfiguration.Trace?.Invoke($"Could not generate delegate for {expressionContext.Request.ActivationType.FullName} using DynamicMethod falling back to linq expressions"); return(base.CompileExpressionResultToDelegate(expressionContext, parameters, extraExpressions, finalExpression)); }
/// <summary> /// Default constructor /// </summary> /// <param name="scope"></param> /// <param name="request"></param> /// <param name="injectionContextCreator"></param> /// <param name="activationStrategy"></param> public DelegateExpression(IInjectionScope scope, IActivationExpressionRequest request, IInjectionContextCreator injectionContextCreator, IActivationStrategy activationStrategy) { _injectionContextCreator = injectionContextCreator; var newRequest = request.NewRequest(typeof(TResult), activationStrategy, typeof(TDelegate), RequestType.Other, null, true); newRequest.DisposalScopeExpression = request.Constants.RootDisposalScope; var activationExpression = request.Services.ExpressionBuilder.GetActivationExpression(scope, newRequest); _action = request.Services.Compiler.CompileDelegate(scope, activationExpression); _funcMethodInfo = typeof(FuncClass).GetTypeInfo().GetDeclaredMethod("Func"); }
/// <summary> /// Get value from scope with no lock /// </summary> /// <typeparam name="T"></typeparam> /// <param name="scope"></param> /// <param name="creationDelegate"></param> /// <param name="uniqueId"></param> /// <returns></returns> public static T GetValueFromScope <T>(IExportLocatorScope scope, ActivationStrategyDelegate creationDelegate, string uniqueId) { var value = scope.GetExtraData(uniqueId); if (value != null) { return((T)value); } value = creationDelegate(scope, scope, null); scope.SetExtraData(uniqueId, value); return((T)value); }
/// <summary> /// Compile a delegate /// </summary> /// <param name="scope">scope</param> /// <param name="compiler">compiler</param> /// <param name="activationType">activation type</param> /// <returns></returns> protected virtual ActivationStrategyDelegate CompileDelegate(IInjectionScope scope, IActivationStrategyCompiler compiler, Type activationType) { var request = compiler.CreateNewRequest(activationType, 1, scope); var expressionResult = GetActivationExpression(scope, request); ActivationStrategyDelegate returnValue = null; if (expressionResult != null) { returnValue = compiler.CompileDelegate(scope, expressionResult); } return(returnValue); }
/// <summary> /// Default constructor /// </summary> /// <param name="scope"></param> /// <param name="request"></param> /// <param name="injectionContextCreator"></param> /// <param name="activationStrategy"></param> public FuncExpression(IInjectionScope scope, IActivationExpressionRequest request, IInjectionContextCreator injectionContextCreator, IActivationStrategy activationStrategy) { _injectionContextCreator = injectionContextCreator; var newRequest = request.NewRequest(typeof(TResult), activationStrategy, typeof(Func <T1, T2, T3, TResult>), RequestType.Other, null, true); newRequest.AddKnownValueExpression(CreateKnownValueExpression(request, typeof(T1), _t1Id)); newRequest.AddKnownValueExpression(CreateKnownValueExpression(request, typeof(T2), _t2Id)); newRequest.AddKnownValueExpression(CreateKnownValueExpression(request, typeof(T3), _t3Id)); newRequest.DisposalScopeExpression = request.Constants.RootDisposalScope; var activationExpression = request.Services.ExpressionBuilder.GetActivationExpression(scope, newRequest); _action = request.Services.Compiler.CompileDelegate(scope, activationExpression); }
/// <summary> /// Default constructor /// </summary> /// <param name="scope"></param> /// <param name="request"></param> /// <param name="injectionContextCreator"></param> /// <param name="activationStrategy"></param> public FuncExpression(IInjectionScope scope, IActivationExpressionRequest request, IInjectionContextCreator injectionContextCreator, IActivationStrategy activationStrategy) { _injectionContextCreator = injectionContextCreator; var requestType = request.ActivationType.GenericTypeArguments[1]; var newRequest = request.NewRequest(requestType, activationStrategy, typeof(Func <TArg1, TResult>), RequestType.Other, null, true); newRequest.AddKnownValueExpression(CreateKnownValueExpression(request)); newRequest.SetLocateKey(request.LocateKey); newRequest.DisposalScopeExpression = request.Constants.RootDisposalScope; var activationExpression = request.Services.ExpressionBuilder.GetActivationExpression(scope, newRequest); _action = request.Services.Compiler.CompileDelegate(scope, activationExpression); }
private object GetInstance(IExportLocatorScope scope, IDisposalScope disposalScope, IInjectionContext context, ActivationStrategyDelegate activationDelegate) { var key = _keyFunc(scope, context); var value = _singletons.GetValueOrDefault(key); if (value != null) { return(value); } value = activationDelegate(scope, disposalScope, context); value = ImmutableHashTree.ThreadSafeAdd(ref _singletons, key, value); return(value); }
/// <summary> /// Get value from scope /// </summary> /// <typeparam name="T"></typeparam> /// <param name="scope"></param> /// <param name="creationDelegate"></param> /// <param name="uniqueId"></param> /// <param name="scopeName"></param> /// <param name="context"></param> /// <param name="staticContext"></param> /// <param name="shareContext"></param> /// <returns></returns> public static T GetValueFromScope <T>(IExportLocatorScope scope, ActivationStrategyDelegate creationDelegate, string uniqueId, string scopeName, bool shareContext, IInjectionContext context, StaticInjectionContext staticContext) { while (scope != null) { if (scope.ScopeName == scopeName) { break; } scope = scope.Parent; } if (scope == null) { throw new NamedScopeLocateException(scopeName, staticContext); } var value = scope.GetExtraData(uniqueId); if (value != null) { return((T)value); } lock (scope.GetLockObject(uniqueId)) { value = scope.GetExtraData(uniqueId); if (value == null) { value = creationDelegate(scope, scope, shareContext ? context : null); scope.SetExtraData(uniqueId, value); } } return((T)value); }
/// <summary> /// Default constructor /// </summary> /// <param name="scope"></param> /// <param name="request"></param> /// <param name="injectionContextCreator"></param> /// <param name="activationStrategy"></param> public DelegateExpression(IInjectionScope scope, IActivationExpressionRequest request, IInjectionContextCreator injectionContextCreator, IActivationStrategy activationStrategy) { _injectionContextCreator = injectionContextCreator; var newRequest = request.NewRequest(typeof(TResult), activationStrategy, typeof(TDelegate), RequestType.Other, null, true); newRequest.AddKnownValueExpression(CreateKnownValueExpression(request, typeof(T1), _arg1Id)); newRequest.AddKnownValueExpression(CreateKnownValueExpression(request, typeof(T2), _arg2Id)); newRequest.AddKnownValueExpression(CreateKnownValueExpression(request, typeof(T3), _arg3Id)); newRequest.SetLocateKey(request.LocateKey); newRequest.DisposalScopeExpression = request.Constants.RootDisposalScope; var activationExpression = request.Services.ExpressionBuilder.GetActivationExpression(scope, newRequest); _action = request.Services.Compiler.CompileDelegate(scope, activationExpression); _funcMethodInfo = typeof(FuncClass).GetTypeInfo().GetDeclaredMethod(nameof(FuncClass.Func)); }
public void DynamicTypeBuilder_StringParam(DynamicTypeBuilder builder, IExportLocatorScope scope, IDisposalScope disposalScope, InjectionContext context) { var proxyType = builder.CreateType(typeof(IComplexProvider <string>), out List <DynamicTypeBuilder.DelegateInfo> methods); string value = "hello world"; DependentService <string> service = null; var func = new ActivationStrategyDelegate((s, d, c) => { Assert.True(c.Keys.Any(key => key.ToString().StartsWith(UniqueStringId.Prefix) && Equals(c.GetExtraData(key), value))); return(service = new DependentService <string>(value)); }); var instance = (IComplexProvider <string>)Activator.CreateInstance(proxyType, scope, disposalScope, context, func); var instanceService = instance.CreateValue(value); Assert.NotNull(instanceService); Assert.Same(service, instanceService); }
/// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="scope"></param> /// <param name="creationDelegate"></param> /// <param name="uniqueId"></param> /// <returns></returns> public static T GetValueFromContext <T>(IExportLocatorScope scope, ActivationStrategyDelegate creationDelegate, string uniqueId) { if (HttpContext.Current != null) { var value = HttpContext.Current.Items[uniqueId]; if (value != null) { return((T)value); } value = creationDelegate(scope, MVCDisposalScopeProvider.GetDisposalScopeFromHttpContext(scope), null); HttpContext.Current.Items[uniqueId] = value; return((T)value); } return((T)creationDelegate(scope, scope, null)); }
/// <summary> /// Compile a delegate /// </summary> /// <param name="scope">scope</param> /// <param name="compiler">compiler</param> /// <param name="activationType">activation type</param> /// <returns></returns> protected override ActivationStrategyDelegate CompileDelegate(IInjectionScope scope, IActivationStrategyCompiler compiler, Type activationType) { var request = compiler.CreateNewRequest(activationType, 1, scope); if (!_wrapperExpressionCreator.SetupWrappersForRequest(scope, request)) { throw new LocateException(request.GetStaticInjectionContext(), "Could not calculate wrapper"); } var expressionResult = GetActivationExpression(scope, request); ActivationStrategyDelegate returnValue = null; if (expressionResult != null) { returnValue = compiler.CompileDelegate(scope, expressionResult); } return(returnValue); }
/// <summary> /// Compile a delegate /// </summary> /// <param name="scope">scope</param> /// <param name="compiler">compiler</param> /// <param name="pair">Pair of activation type and locate key.</param> /// <returns></returns> protected virtual ActivationStrategyDelegate CompileDelegate( IInjectionScope scope, IActivationStrategyCompiler compiler, Tuple <Type, object> pair) { var request = compiler.CreateNewRequest(pair.Item1, 1, scope); if (pair.Item2 != null) { request.SetLocateKey(pair.Item2); } var expressionResult = GetActivationExpression(scope, request); ActivationStrategyDelegate returnValue = null; if (expressionResult != null) { returnValue = compiler.CompileDelegate(scope, expressionResult); } return(returnValue); }
/// <summary> /// Get value from scope using lock /// </summary> /// <typeparam name="T"></typeparam> /// <param name="scope"></param> /// <param name="creationDelegate"></param> /// <param name="uniqueId"></param> /// <param name="shareContext"></param> /// <param name="context"></param> /// <returns></returns> public static T GetValueFromScopeThreadSafe <T>(IExportLocatorScope scope, ActivationStrategyDelegate creationDelegate, string uniqueId, bool shareContext, IInjectionContext context) { var value = scope.GetExtraData(uniqueId); if (value != null) { return((T)value); } lock (scope.GetLockObject(uniqueId)) { value = scope.GetExtraData(uniqueId); if (value == null) { value = creationDelegate(scope, scope, shareContext ? context : null); scope.SetExtraData(uniqueId, value); } } return((T)value); }
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)); }
public T GetOrCreateScopedService<T>(int id, ActivationStrategyDelegate createDelegate, IInjectionContext context) { var initialStorage = InternalScopedStorage; var storage = initialStorage; while (!ReferenceEquals(storage, ScopedStorage.Empty)) { if (storage.Id == id) { return (T)storage.ScopedService; } storage = storage.Next; } var value = createDelegate(this, this, context); if (Interlocked.CompareExchange(ref InternalScopedStorage, new ScopedStorage { Id = id, Next = initialStorage, ScopedService = value }, initialStorage) == initialStorage) { return (T)value; } return HandleScopedStorageCollision<T>(id, (T)value); }
/// <summary> /// Constructor /// </summary> /// <param name="activationDelegate">Delegate for create the wrapped service.</param> /// <param name="locateKey">Key of wrapped service.</param> public GraceOptionalFactory(ActivationStrategyDelegate activationDelegate, object locateKey) { _delegate = activationDelegate; qualifier = locateKey as string; }