/// <summary> /// Get an activation expression for a request /// </summary> /// <param name="scope">scope for request</param> /// <param name="request">request</param> /// <returns></returns> public IActivationExpressionResult GetActivationExpression(IInjectionScope scope, IActivationExpressionRequest request) { if (SetupWrappersForRequest(scope, request)) { var wrapper = request.PopWrapperPathNode(); return(wrapper.GetActivationExpression(scope, request)); } return(null); }
/// <summary> /// Get expression result from request /// </summary> /// <param name="scope"></param> /// <param name="request"></param> /// <param name="activationType"></param> /// <param name="key"></param> /// <returns></returns> protected virtual IActivationExpressionResult GetValueFromRequest(IInjectionScope scope, IActivationExpressionRequest request, Type activationType, object key) { var knownValues = request.KnownValueExpressions.Where( v => activationType.GetTypeInfo().IsAssignableFrom(v.ActivationType.GetTypeInfo())).ToArray(); if (knownValues.Length > 0) { if (knownValues.Length == 1) { return(knownValues[0].ValueExpression(request)); } if (key != null) { IKnownValueExpression knownValue; if (key is string keyString) { knownValue = knownValues.FirstOrDefault(v => string.Compare(keyString, v.Key as string, StringComparison.CurrentCultureIgnoreCase) == 0); } else { knownValue = knownValues.FirstOrDefault(v => v.Key == key); } if (knownValue != null) { return(knownValue.ValueExpression(request)); } } if (request.Info is MemberInfo memberInfo) { var knownValue = knownValues.FirstOrDefault(v => Equals(v.Key, memberInfo.Name)); if (knownValue != null) { return(knownValue.ValueExpression(request)); } } if (request.Info is ParameterInfo parameterInfo) { var knownValue = knownValues.FirstOrDefault(v => Equals(v.Key, parameterInfo.Name)); if (knownValue != null) { return(knownValue.ValueExpression(request)); } knownValue = knownValues.FirstOrDefault(v => Equals(v.Position.GetValueOrDefault(-1), parameterInfo.Position)); if (knownValue != null) { return(knownValue.ValueExpression(request)); } } return(knownValues[0].ValueExpression(request)); } if (request.WrapperPathNode != null) { var configuration = request.WrapperPathNode.Strategy.GetActivationConfiguration(activationType); if (activationType.GetTypeInfo().IsAssignableFrom(configuration.ActivationType.GetTypeInfo())) { var wrapper = request.PopWrapperPathNode(); return(ProcessPathNode(scope, request, activationType, wrapper)); } } else if (request.DecoratorPathNode != null) { var configuration = request.DecoratorPathNode.Strategy.GetActivationConfiguration(activationType); if (activationType.GetTypeInfo().IsAssignableFrom(configuration.ActivationType.GetTypeInfo())) { var decorator = request.PopDecoratorPathNode(); return(ProcessPathNode(scope, request, activationType, decorator)); } } if (request.ActivationType == typeof(IInjectionScope)) { if (!scope.ScopeConfiguration.Behaviors.AllowInjectionScopeLocation) { throw new ImportInjectionScopeException(request.GetStaticInjectionContext()); } var method = typeof(IExportLocatorScopeExtensions).GetRuntimeMethod("GetInjectionScope", new[] { typeof(IExportLocatorScope) }); var expression = Expression.Call(method, request.ScopeParameter); return(request.Services.Compiler.CreateNewResult(request, expression)); } if (request.ActivationType == typeof(IExportLocatorScope) || request.ActivationType == typeof(ILocatorService)) { return(request.Services.Compiler.CreateNewResult(request, request.ScopeParameter)); } if (request.ActivationType == typeof(IDisposalScope) || (request.ActivationType == typeof(IDisposable) && request.RequestingScope.ScopeConfiguration.InjectIDisposable)) { return(request.Services.Compiler.CreateNewResult(request, request.DisposalScopeExpression)); } if (request.ActivationType == typeof(IInjectionContext)) { request.RequireInjectionContext(); return(request.Services.Compiler.CreateNewResult(request, request.InjectionContextParameter)); } if (request.ActivationType == typeof(StaticInjectionContext)) { var staticContext = request.Parent != null? request.Parent.GetStaticInjectionContext() : request.GetStaticInjectionContext(); return(request.Services.Compiler.CreateNewResult(request, Expression.Constant(staticContext))); } if (request.IsDynamic) { var dynamicMethod = typeof(ActivationExpressionBuilder).GetRuntimeMethod("GetDynamicValue", new[] { typeof(IExportLocatorScope), typeof(IDisposalScope), typeof(StaticInjectionContext), typeof(IInjectionContext), typeof(object), typeof(bool), typeof(bool), typeof(object) }); var closedMethod = dynamicMethod.MakeGenericMethod(request.ActivationType); Expression defaultExpression = Expression.Constant(request.DefaultValue?.DefaultValue, typeof(object)); var expression = Expression.Call(closedMethod, request.ScopeParameter, request.DisposalScopeExpression, Expression.Constant(request.GetStaticInjectionContext()), request.InjectionContextParameter, Expression.Constant(request.LocateKey, typeof(object)), Expression.Constant(request.IsRequired), Expression.Constant(request.DefaultValue != null), defaultExpression); return(request.Services.Compiler.CreateNewResult(request, expression)); } return(null); }
/// <summary> /// Get expression result from request /// </summary> /// <param name="scope"></param> /// <param name="request"></param> /// <param name="activationType"></param> /// <param name="key"></param> /// <returns></returns> protected virtual IActivationExpressionResult GetValueFromRequest(IInjectionScope scope, IActivationExpressionRequest request, Type activationType, object key) { var knownValue = request.KnownValueExpressions.FirstOrDefault( v => activationType.GetTypeInfo().IsAssignableFrom(v.ActivationType.GetTypeInfo())); if (knownValue != null) { return(knownValue.ValueExpression(request)); } if (request.WrapperPathNode != null) { var configuration = request.WrapperPathNode.Strategy.GetActivationConfiguration(activationType); if (activationType.GetTypeInfo().IsAssignableFrom(configuration.ActivationType.GetTypeInfo())) { var wrapper = request.PopWrapperPathNode(); return(ProcessPathNode(scope, request, activationType, wrapper)); } } else if (request.DecoratorPathNode != null) { var configuration = request.DecoratorPathNode.Strategy.GetActivationConfiguration(activationType); if (activationType.GetTypeInfo().IsAssignableFrom(configuration.ActivationType.GetTypeInfo())) { var decorator = request.PopDecoratorPathNode(); return(ProcessPathNode(scope, request, activationType, decorator)); } } if (request.ActivationType == typeof(IInjectionScope)) { if (!scope.ScopeConfiguration.Behaviors.AllowInjectionScopeLocation) { throw new ImportInjectionScopeException(request.GetStaticInjectionContext()); } var method = typeof(IExportLocatorScopeExtensions).GetRuntimeMethod("GetInjectionScope", new[] { typeof(IExportLocatorScope) }); var expression = Expression.Call(method, request.Constants.ScopeParameter); return(request.Services.Compiler.CreateNewResult(request, expression)); } if (request.ActivationType == typeof(IExportLocatorScope) || request.ActivationType == typeof(ILocatorService)) { return(request.Services.Compiler.CreateNewResult(request, request.Constants.ScopeParameter)); } if (request.ActivationType == typeof(IInjectionContext)) { request.RequireInjectionContext(); return(request.Services.Compiler.CreateNewResult(request, request.Constants.InjectionContextParameter)); } if (request.ActivationType == typeof(StaticInjectionContext)) { var staticContext = request.Parent != null? request.Parent.GetStaticInjectionContext() : request.GetStaticInjectionContext(); return(request.Services.Compiler.CreateNewResult(request, Expression.Constant(staticContext))); } if (request.IsDynamic) { var dynamicMethod = typeof(ActivationExpressionBuilder).GetRuntimeMethod("GetDynamicValue", new[] { typeof(IExportLocatorScope), typeof(IDisposalScope), typeof(StaticInjectionContext), typeof(IInjectionContext), typeof(object), typeof(bool), typeof(bool), typeof(object) }); var closedMethod = dynamicMethod.MakeGenericMethod(request.ActivationType); Expression defaultExpression = Expression.Constant(request.DefaultValue?.DefaultValue, typeof(object)); var expression = Expression.Call(closedMethod, request.Constants.ScopeParameter, request.DisposalScopeExpression, Expression.Constant(request.GetStaticInjectionContext()), request.Constants.InjectionContextParameter, Expression.Constant(request.LocateKey, typeof(object)), Expression.Constant(request.IsRequired), Expression.Constant(request.DefaultValue != null), defaultExpression); return(request.Services.Compiler.CreateNewResult(request, expression)); } return(null); }
/// <summary> /// Get an activation expression for a request /// </summary> /// <param name="scope">scope for request</param> /// <param name="request">request</param> /// <returns></returns> public IActivationExpressionResult GetActivationExpression(IInjectionScope scope, IActivationExpressionRequest request) { Type wrappedType; var wrappers = GetWrappers(scope, request.ActivationType, request, out wrappedType); if (wrappers != ImmutableLinkedList <IActivationPathNode> .Empty) { if (request.DecoratorPathNode != null && wrappedType.GetTypeInfo().IsAssignableFrom(request.DecoratorPathNode.Strategy.ActivationType.GetTypeInfo())) { var decorator = request.PopDecoratorPathNode(); wrappers = ImmutableLinkedList <IActivationPathNode> .Empty.Add(decorator).AddRange(wrappers.Reverse()); } else { var collection = scope.StrategyCollectionContainer.GetActivationStrategyCollection(wrappedType); if (collection == null && wrappedType.IsConstructedGenericType) { var generic = wrappedType.GetGenericTypeDefinition(); collection = scope.StrategyCollectionContainer.GetActivationStrategyCollection(generic); } if (collection != null) { var primary = request.Filter == null?collection.GetPrimary() : null; if (primary != null) { wrappers = ImmutableLinkedList <IActivationPathNode> .Empty.Add(new WrapperActivationPathNode(primary, wrappedType, null)).AddRange(wrappers.Reverse()); } else { foreach (var strategy in collection.GetStrategies()) { var pass = true; if (strategy.HasConditions) { foreach (var condition in strategy.Conditions) { if (!condition.MeetsCondition(strategy, request.GetStaticInjectionContext())) { pass = false; break; } } } if (pass && (request.Filter == null || request.Filter(strategy))) { wrappers = ImmutableLinkedList <IActivationPathNode> .Empty.Add(new WrapperActivationPathNode(strategy, wrappedType, null)).AddRange(wrappers.Reverse()); } } } } else { return(null); } } request.SetWrapperPath(wrappers); var wrapper = request.PopWrapperPathNode(); return(wrapper.GetActivationExpression(scope, request)); } return(null); }