예제 #1
0
            protected virtual object LocateFromChildContainer(IInjectionContextValueProvider valueProvider,
                                                              IExportLocatorScope scope,
                                                              StaticInjectionContext staticContext,
                                                              Type type,
                                                              object key,
                                                              IInjectionContext context,
                                                              object defaultValue,
                                                              bool useDefault,
                                                              bool isRequired)
            {
                var value = valueProvider.GetValueFromInjectionContext(scope, type, key, context, false);

                if (value != null)
                {
                    return(value);
                }

                if (scope.TryLocate(type, out value, context, withKey: key))
                {
                    return(value);
                }

                if (useDefault)
                {
                    return(defaultValue);
                }

                if (isRequired)
                {
                    throw new LocateException(staticContext);
                }

                return(null);
            }
예제 #2
0
        private static string CreateMessage(StaticInjectionContext context, string message = null)
        {
            var infoStack = new List <InjectionTargetInfo>(context.InjectionStack.Reverse());
            var builder   = new StringBuilder();

            builder.AppendLine(message ?? $"Could not locate Type {context.ActivationType}");

            if (infoStack.Count > 40)
            {
                for (var i = 0; i < 20; i++)
                {
                    CreateMessageForTargetInfo(builder, infoStack[i], i + 1);
                }

                builder.AppendLine();
                builder.AppendLine($"Dropped {infoStack.Count - 40} entries");
                builder.AppendLine();

                for (var i = infoStack.Count - 20; i < infoStack.Count; i++)
                {
                    CreateMessageForTargetInfo(builder, infoStack[i], i + 1);
                }
            }
            else
            {
                for (var i = 0; i < infoStack.Count; i++)
                {
                    CreateMessageForTargetInfo(builder, infoStack[i], i + 1);
                }
            }

            return(builder.ToString());
        }
예제 #3
0
        /// <summary>
        /// Find decorators for a given type
        /// </summary>
        /// <param name="scope"></param>
        /// <param name="request"></param>
        /// <param name="type"></param>
        /// <param name="strategy"></param>
        /// <returns></returns>
        protected virtual List <ICompiledDecoratorStrategy> FindDecoratorsForType(IInjectionScope scope, IActivationExpressionRequest request, Type type, ICompiledExportStrategy strategy)
        {
            List <ICompiledDecoratorStrategy> decorators             = new List <ICompiledDecoratorStrategy>();
            StaticInjectionContext            staticInjectionContext = null;
            var collection =
                scope.DecoratorCollectionContainer.GetActivationStrategyCollection(type);

            if (collection != null)
            {
                foreach (var decorator in collection.GetStrategies())
                {
                    if (decorator.HasConditions)
                    {
                        if (staticInjectionContext == null)
                        {
                            staticInjectionContext = request.GetStaticInjectionContext();
                        }

                        if (!decorator.Conditions.All(
                                condition => condition.MeetsCondition(strategy, staticInjectionContext)))
                        {
                            continue;
                        }
                    }

                    decorators.Add(decorator);
                }
            }

            if (type.IsConstructedGenericType)
            {
                var generic = type.GetGenericTypeDefinition();

                collection = scope.DecoratorCollectionContainer.GetActivationStrategyCollection(generic);

                if (collection != null)
                {
                    foreach (var decorator in collection.GetStrategies())
                    {
                        if (decorator.HasConditions)
                        {
                            if (staticInjectionContext == null)
                            {
                                staticInjectionContext = request.GetStaticInjectionContext();
                            }

                            if (!decorator.Conditions.All(
                                    condition => condition.MeetsCondition(strategy, staticInjectionContext)))
                            {
                                continue;
                            }
                        }

                        decorators.Add(decorator);
                    }
                }
            }

            return(decorators);
        }
예제 #4
0
        /// <summary>
        /// Test if being injected into a specific type
        /// </summary>
        /// <param name="strategy">strategy to test</param>
        /// <param name="staticInjectionContext">static injection context</param>
        /// <returns></returns>
        public bool MeetsCondition(IActivationStrategy strategy, StaticInjectionContext staticInjectionContext)
        {
            var targetInfo =
                staticInjectionContext.InjectionStack.FirstOrDefault(
                    info => info.RequestingStrategy?.StrategyType == ActivationStrategyType.ExportStrategy);

            return(targetInfo?.InjectionType != null && _typeTest(targetInfo.InjectionType));
        }
예제 #5
0
        /// <summary>
        /// Check value for null
        /// </summary>
        /// <typeparam name="T">type of value</typeparam>
        /// <param name="context">static context</param>
        /// <param name="value">value to check</param>
        /// <returns>non null value</returns>
        public static T CheckForNull <T>(StaticInjectionContext context, T value)
        {
            if (value == null)
            {
                throw new NullValueProvidedException(context);
            }

            return(value);
        }
예제 #6
0
        public virtual object PostBuildUp(object value, StaticInjectionContext staticContext, IExportLocatorScope scope,
                                          IInjectionContext injectionContext)
        {
            var timer = (Stopwatch)injectionContext.GetExtraData(staticContext.TargetInfo.UniqueId);

            timer.Stop();

            return(value);
        }
예제 #7
0
        /// <summary>
        /// Default constructor
        /// </summary>
        /// <param name="context">static context required</param>
        /// <param name="message">message, this is not required</param>
        public LocateException(StaticInjectionContext context, string message = null) : base(CreateMessage(context, message))
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            Context = context;
        }
예제 #8
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="childScope"></param>
        /// <param name="disposalScope"></param>
        /// <param name="name"></param>
        /// <param name="extraData"></param>
        /// <param name="consider"></param>
        /// <param name="allowNull"></param>
        /// <returns></returns>
        object IInjectionScope.LocateByNameFromChildScope(IExportLocatorScope childScope, IDisposalScope disposalScope,
                                                          string name,
                                                          object extraData, ActivationStrategyFilter consider, bool allowNull)
        {
            var collection = StrategyCollectionContainer.GetActivationStrategyCollectionByName(name);

            ICompiledExportStrategy strategy = null;

            if (collection != null)
            {
                if (consider != null)
                {
                    var context = new StaticInjectionContext(typeof(object));

                    strategy =
                        collection.GetStrategies()
                        .FirstOrDefault(
                            s => (!s.HasConditions || s.Conditions.All(con => con.MeetsCondition(s, context))) && consider(s));
                }
                else
                {
                    strategy = collection.GetPrimary();

                    if (strategy == null)
                    {
                        var context = new StaticInjectionContext(typeof(object));

                        strategy = collection.GetStrategies()
                                   .FirstOrDefault(
                            s => !s.HasConditions || s.Conditions.All(con => con.MeetsCondition(s, context)));
                    }
                }
            }

            if (strategy != null)
            {
                var strategyDelegate =
                    strategy.GetActivationStrategyDelegate(this, InternalFieldStorage.ActivationStrategyCompiler, typeof(object));

                return(strategyDelegate(childScope, disposalScope, CreateContext(extraData)));
            }

            if (Parent != null)
            {
                return(((IInjectionScope)Parent).LocateByNameFromChildScope(childScope, disposalScope, name, extraData,
                                                                            consider, allowNull));
            }

            if (!allowNull)
            {
                throw new LocateException(new StaticInjectionContext(typeof(object)));
            }

            return(null);
        }
예제 #9
0
        public virtual object PreBuildUp(StaticInjectionContext staticContext, IExportLocatorScope scope,
                                         IInjectionContext injectionContext)
        {
            var timer = new Stopwatch();

            injectionContext.SetExtraData(staticContext.TargetInfo.UniqueId, timer);

            timer.Start();

            return(null);
        }
예제 #10
0
 /// <summary>
 /// Default constructor
 /// </summary>
 /// <param name="factories"></param>
 /// <param name="name"></param>
 /// <param name="attributes"></param>
 /// <param name="defaultValue"></param>
 /// <param name="staticInjectionContext"></param>
 public BindingSourceHelper(IReadOnlyList <IValueProviderFactory> factories,
                            string name,
                            IEnumerable <object> attributes,
                            object defaultValue,
                            StaticInjectionContext staticInjectionContext)
 {
     _factories              = factories;
     _name                   = name;
     _defaultValue           = defaultValue;
     _staticInjectionContext = staticInjectionContext;
     _binding                = BindingInfo.GetBindingInfo(attributes);
 }
예제 #11
0
        /// <summary>
        /// Execute delegate by injecting parameters then executing
        /// </summary>
        /// <param name="scope"></param>
        /// <param name="context"></param>
        /// <param name="injectionContext"></param>
        /// <param name="delegate"></param>
        /// <returns></returns>
        public static object InjectAndExecuteDelegate(IExportLocatorScope scope, StaticInjectionContext context,
                                                      IInjectionContext injectionContext, Delegate @delegate)
        {
            var executeFunc = _executeDelegateWithInjections.GetValueOrDefault(@delegate.GetType());

            if (executeFunc == null)
            {
                executeFunc = CreateExecuteDelegate(@delegate);

                _executeDelegateWithInjections = _executeDelegateWithInjections.Add(@delegate.GetType(), executeFunc);
            }

            return(executeFunc(scope, context, injectionContext, @delegate));
        }
예제 #12
0
        /// <summary>
        /// Test if strategy meets condition
        /// </summary>
        /// <param name="strategy">strategy to test</param>
        /// <param name="staticInjectionContext">static injection context</param>
        /// <returns>meets condition</returns>
        public bool MeetsCondition(IActivationStrategy strategy, StaticInjectionContext staticInjectionContext)
        {
            var targetInfo = staticInjectionContext.TargetInfo;

            if (targetInfo != null)
            {
                foreach (var attribute in targetInfo.InjectionTypeAttributes)
                {
                    if (attribute.GetType() == _attributeType && (_filter == null || _filter(attribute)))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
예제 #13
0
        /// <summary>
        /// Check for null and then add to disposal scope
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="disposalScope"></param>
        /// <param name="context"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static T CheckForNullAndAddToDisposalScope <T>(IDisposalScope disposalScope,
                                                              StaticInjectionContext context, T value)
        {
            if (value == null)
            {
                throw new NullValueProvidedException(context);
            }

            var disposable = value as IDisposable;

            if (disposable != null)
            {
                disposalScope.AddDisposable(disposable);
            }

            return(value);
        }
예제 #14
0
        /// <summary>
        /// Test if strategy meets condition
        /// </summary>
        /// <param name="strategy">strategy to test</param>
        /// <param name="staticInjectionContext">static injection context</param>
        /// <returns>meets condition</returns>
        public bool MeetsCondition(IActivationStrategy strategy, StaticInjectionContext staticInjectionContext)
        {
            var targetInfo = staticInjectionContext.InjectionStack.FirstOrDefault(
                info => info.RequestingStrategy?.StrategyType == ActivationStrategyType.ExportStrategy);

            if (targetInfo != null)
            {
                foreach (var attribute in targetInfo.InjectionTypeAttributes)
                {
                    if (attribute.GetType() == _attributeType && (_filter == null || _filter(attribute)))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
예제 #15
0
        /// <summary>
        /// Test if strategy meets condition
        /// </summary>
        /// <param name="strategy">strategy to test</param>
        /// <param name="staticInjectionContext">static injection context</param>
        /// <returns>meets condition</returns>
        public bool MeetsCondition(IActivationStrategy strategy, StaticInjectionContext staticInjectionContext)
        {
            var targetInfo = staticInjectionContext.TargetInfo;

            if (targetInfo != null)
            {
                foreach (var attribute in targetInfo.InjectionMemberAttributes)
                {
                    var attrT = attribute as TAttribute;

                    if (attrT != null && (_filter == null || _filter(attrT)))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
예제 #16
0
        /// <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);
        }
예제 #17
0
        /// <summary>
        /// Test if strategy meets condition at configuration time
        /// </summary>
        /// <param name="strategy">strategy to test</param>
        /// <param name="staticInjectionContext">static injection context</param>
        /// <returns>meets condition</returns>
        public bool MeetsCondition(IActivationStrategy strategy, StaticInjectionContext staticInjectionContext)
        {
            if (_decoratedType.GetTypeInfo().IsGenericTypeDefinition)
            {
                var current = strategy.ActivationType;

                while (current != null && current != typeof(object))
                {
                    if (current.IsConstructedGenericType && current.GetGenericTypeDefinition() == _decoratedType)
                    {
                        return(true);
                    }

                    current = current.GetTypeInfo().BaseType;
                }

                return(false);
            }

            return(strategy.ActivationType.IsAssignableFrom(_decoratedType));
        }
예제 #18
0
        private string GetAncestorRequestId(StaticInjectionContext context)
        {
            var typeInfo = _ancestorType.GetTypeInfo();

            var injectionInfoTarget = context.InjectionStack.FirstOrDefault(target =>
            {
                var injectionInfo = target.InjectionType?.GetTypeInfo();

                if (injectionInfo != null && typeInfo.IsAssignableFrom(injectionInfo))
                {
                    return(true);
                }

                return(false);
            });

            if (injectionInfoTarget == null)
            {
                throw new LocateException(context, $"Could not find ancestor type {_ancestorType.Name}");
            }

            return(injectionInfoTarget.UniqueId);
        }
예제 #19
0
        /// <summary>
        /// Get a value dynamically
        /// </summary>
        /// <typeparam name="T">value to get</typeparam>
        /// <param name="scope">scope</param>
        /// <param name="disposalScope">disposal scope to use</param>
        /// <param name="staticInjectionContext">static injection context </param>
        /// <param name="context">context for call</param>
        /// <param name="key"></param>
        /// <param name="isRequired"></param>
        /// <param name="hasDefault"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public static T GetDynamicValue <T>(IExportLocatorScope scope, IDisposalScope disposalScope, StaticInjectionContext staticInjectionContext,
                                            IInjectionContext context, object key, bool isRequired, bool hasDefault, object defaultValue)
        {
            var injectionScope = scope.GetInjectionScope();

            var value = injectionScope.LocateFromChildScope(scope, disposalScope, typeof(T), context, null, key, true, true);

            if (value != null)
            {
                return((T)value);
            }

            if (hasDefault)
            {
                return((T)defaultValue);
            }

            if (isRequired)
            {
                throw new LocateException(staticInjectionContext, $"Could not locate dynamic value for type {typeof(T).FullName}");
            }

            return(default(T));
        }
예제 #20
0
        /// <summary>
        /// Get data from injection context
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="locator"></param>
        /// <param name="staticContext"></param>
        /// <param name="key"></param>
        /// <param name="dataProvider"></param>
        /// <param name="defaultValue"></param>
        /// <param name="useDefault"></param>
        /// <param name="isRequired"></param>
        /// <returns></returns>
        public virtual T GetValueFromInjectionContext <T>(IExportLocatorScope locator,
                                                          StaticInjectionContext staticContext,
                                                          object key,
                                                          IInjectionContext dataProvider,
                                                          object defaultValue,
                                                          bool useDefault,
                                                          bool isRequired)
        {
            object value = null;

            if (dataProvider != null)
            {
                GetValueFromExtraDataProvider <T>(key, dataProvider, out value);

                if (value == null)
                {
                    if (dataProvider.ExtraData is T)
                    {
                        value = dataProvider.ExtraData;
                    }
                    else
                    {
                        var delegateInstance = dataProvider.ExtraData as Delegate;

                        if (delegateInstance != null && delegateInstance.GetMethodInfo().ReturnType == typeof(T))
                        {
                            value = delegateInstance;
                        }
                    }
                }
            }

            if (value == null)
            {
                var currentLocator = locator;

                while (currentLocator != null)
                {
                    if (GetValueFromExtraDataProvider <T>(key, currentLocator, out value))
                    {
                        break;
                    }

                    currentLocator = currentLocator.Parent;
                }
            }

            if (value == null && useDefault)
            {
                value = defaultValue;
            }

            if (value != null)
            {
                if (value is Delegate)
                {
                    value =
                        ReflectionService.InjectAndExecuteDelegate(locator, staticContext, dataProvider, value as Delegate);
                }

                if (!(value is T))
                {
                    try
                    {
                        value = Convert.ChangeType(value, typeof(T));
                    }
                    catch (Exception exp)
                    {
                        // to do fix up exception
                        throw new LocateException(staticContext, exp);
                    }
                }
            }
            else if (isRequired && !useDefault)
            {
                throw new LocateException(staticContext);
            }

            return((T)value);
        }
예제 #21
0
 /// <summary>
 /// Default constructor
 /// </summary>
 /// <param name="scopeName">scope name</param>
 /// <param name="context">static injection context</param>
 public NamedScopeLocateException(string scopeName, StaticInjectionContext context) : base(context, $"Could not locate scope with name {scopeName}")
 {
     ScopeName = scopeName;
 }
예제 #22
0
 /// <summary>
 /// Default constructor takes context
 /// </summary>
 /// <param name="context">static injection context</param>
 public ImportInjectionScopeException(StaticInjectionContext context) : base(context, ErrorMessage)
 {
 }
예제 #23
0
 /// <summary>
 /// Default constructor
 /// </summary>
 /// <param name="context"></param>
 public NullValueProvidedException(StaticInjectionContext context) :
     base(context, $"Null value provided from factory for {ReflectionService.GetFriendlyNameForType(context.ActivationType, true)}")
 {
 }
예제 #24
0
        /// <summary>
        /// Gets value from injection context
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="locator"></param>
        /// <param name="staticContext"></param>
        /// <param name="key"></param>
        /// <param name="dataProvider"></param>
        /// <param name="defaultValue"></param>
        /// <param name="useDefault"></param>
        /// <param name="isRequired"></param>
        /// <returns></returns>
        public static T GetValueFromInjectionContext <T>(
            IExportLocatorScope locator,
            StaticInjectionContext staticContext,
            object key,
            IInjectionContext dataProvider,
            object defaultValue,
            bool useDefault,
            bool isRequired)
        {
            object value = null;

            if (dataProvider != null)
            {
                value = GetValueFromExtraDataProvider <T>(key, dataProvider);
            }

            if (value == null)
            {
                var currentLocator = locator;

                while (currentLocator != null && value == null)
                {
                    value = GetValueFromExtraDataProvider <T>(key, currentLocator);

                    currentLocator = currentLocator.Parent;
                }
            }

            if (value == null && useDefault)
            {
                value = defaultValue;
            }

            if (value != null)
            {
                if (value is Delegate)
                {
                    value =
                        ReflectionService.InjectAndExecuteDelegate(locator, staticContext, dataProvider, value as Delegate);
                }

                if (!typeof(T).GetTypeInfo().IsAssignableFrom(value.GetType().GetTypeInfo()))
                {
                    try
                    {
                        value = Convert.ChangeType(value, typeof(T));
                    }
                    catch (Exception exp)
                    {
                        // to do fix up exception
                        throw new LocateException(staticContext, exp);
                    }
                }
            }
            else if (isRequired && !useDefault)
            {
                throw new LocateException(staticContext);
            }

            return((T)value);
        }
예제 #25
0
 /// <summary>
 /// Test if condition is meet
 /// </summary>
 /// <param name="strategy">strategy to test</param>
 /// <param name="staticInjectionContext">static injection context</param>
 /// <returns>true if condition is meet</returns>
 public bool MeetsCondition(IActivationStrategy strategy, StaticInjectionContext staticInjectionContext)
 {
     return(_condition(strategy, staticInjectionContext));
 }
예제 #26
0
        /// <summary>
        /// Test if being injected into a specific type
        /// </summary>
        /// <param name="strategy">strategy to test</param>
        /// <param name="staticInjectionContext">static injection context</param>
        /// <returns></returns>
        public bool MeetsCondition(IActivationStrategy strategy, StaticInjectionContext staticInjectionContext)
        {
            var targetInfo = staticInjectionContext.TargetInfo;

            return(targetInfo?.InjectionType != null && _typeTest(targetInfo.InjectionType));
        }
예제 #27
0
 /// <summary>
 /// Constructor that takes an inner exception
 /// </summary>
 /// <param name="context">static context</param>
 /// <param name="innerException">inner exception</param>
 /// <param name="message">message for exception</param>
 public LocateException(StaticInjectionContext context, Exception innerException, string message = null) : base(CreateMessage(context, message), innerException)
 {
     Context = context;
 }
예제 #28
0
 /// <summary>
 /// Default constructor
 /// </summary>
 /// <param name="context"></param>
 public RecursiveLocateException(StaticInjectionContext context) : base(context, "Recursive object graph detected")
 {
 }