Esempio n. 1
0
        private bool TryResolve(Type type, string key, ResolutionContext context, out BoundActivation resolved)
        {
            Debug.Assert(_lock.IsReadLockHeld);

            var regKey = new RegistrationKey(type, key);

            if (context.WouldCreateCycle(regKey))
            {
                resolved = null;
                return(false);
            }

            using (context.Activating(regKey))
            {
                // fast path: the type has a provider registered
                if (_registrations.TryGetValue(regKey, out var reg))
                {
                    resolved = new BoundActivation(reg);
                    return(true);
                }

                // there's nothing registered for the type - see if we can form an implicit
                // registration based on its constructors and what is registered.
                ConstructorInfo[] ctors = type.GetConstructors()
                                          .OrderByDescending(ci => ci.GetParameters().Length)
                                          .ToArray();

                for (int i = 0; i < ctors.Length; i++)
                {
                    ConstructorInfo   ctor       = ctors[i];
                    ParameterInfo[]   pis        = ctor.GetParameters();
                    BoundActivation[] parameters = new BoundActivation[pis.Length];
                    bool allBound = true;

                    for (int p = 0;
                         allBound && p < pis.Length;
                         p++)
                    {
                        string          bindingKey = null;
                        BoundActivation paramProvider;

                        var bindingKeyAttr = pis[p].GetCustomAttribute <BindingKeyAttribute>();
                        if (!(bindingKeyAttr is null))
                        {
                            bindingKey = bindingKeyAttr.Key;
                        }

                        if (TryResolve(pis[p].ParameterType, bindingKey, context, out paramProvider))
                        {
                            // exact match with the binding key in this or parent.
                            parameters[p] = paramProvider;
                        }
                        else if (!(bindingKeyAttr is null) &&
                                 bindingKeyAttr.FallbackToDefaultBinding &&
                                 TryResolve(pis[p].ParameterType, null, context, out paramProvider))
                        {
                            // exact match with the fallback key in this or parent.
                            parameters[p] = paramProvider;
                        }
Esempio n. 2
0
        private static bool ContainsCycle(BoundActivation a, Stack <Type> types)
        {
            if (types.Contains(a.Type))
            {
                return(true);
            }

            types.Push(a.Type);

            if (!(a._parameters is null))
            {
                for (int i = 0; i < a._parameters.Length; i++)
                {
                    if (ContainsCycle(a._parameters[i], types))
                    {
                        return(true);
                    }
                }
            }

            types.Pop();
            return(false);
        }