예제 #1
0
        internal object ConstructType(
            Type implementationType,
            ConstructorInfo constructor,
            DependencyContainerResolveOptions options = null)
        {
            var typeToConstruct = implementationType;

            if (constructor == null)
            {
                // Try and get the best constructor that we can construct
                // if we can't construct any then get the constructor
                // with the least number of parameters so we can throw a meaningful
                // resolve exception
                constructor = GetBestConstructor(typeToConstruct, options) ??
                              GetTypeConstructors(typeToConstruct).LastOrDefault();
            }

            if (constructor == null)
            {
                throw new DependencyContainerResolutionException(typeToConstruct);
            }

            var ctorParams = constructor.GetParameters();
            var args       = new object[ctorParams.Length];

            for (var parameterIndex = 0; parameterIndex < ctorParams.Length; parameterIndex++)
            {
                var currentParam = ctorParams[parameterIndex];

                try
                {
                    args[parameterIndex] = options?.ConstructorParameters.GetValueOrDefault(currentParam.Name, ResolveInternal(new DependencyContainer.TypeRegistration(currentParam.ParameterType), options.Clone()));
                }
                catch (DependencyContainerResolutionException ex)
                {
                    // If a constructor parameter can't be resolved
                    // it will throw, so wrap it and throw that this can't
                    // be resolved.
                    throw new DependencyContainerResolutionException(typeToConstruct, ex);
                }
                catch (Exception ex)
                {
                    throw new DependencyContainerResolutionException(typeToConstruct, ex);
                }
            }

            try
            {
                return(CreateObjectConstructionDelegateWithCache(constructor).Invoke(args));
            }
            catch (Exception ex)
            {
                throw new DependencyContainerResolutionException(typeToConstruct, ex);
            }
        }
예제 #2
0
        private bool CanConstruct(
            ConstructorInfo ctor,
            DependencyContainerResolveOptions options)
        {
            foreach (var parameter in ctor.GetParameters())
            {
                if (string.IsNullOrEmpty(parameter.Name))
                {
                    return(false);
                }

                var isParameterOverload = options.ConstructorParameters.ContainsKey(parameter.Name);

                if (parameter.ParameterType.IsPrimitive && !isParameterOverload)
                {
                    return(false);
                }

                if (!isParameterOverload &&
                    !CanResolve(new DependencyContainer.TypeRegistration(parameter.ParameterType), options.Clone()))
                {
                    return(false);
                }
            }

            return(true);
        }
예제 #3
0
        internal bool CanResolve(
            DependencyContainer.TypeRegistration registration,
            DependencyContainerResolveOptions options = null)
        {
            if (options == null)
            {
                options = DependencyContainerResolveOptions.Default;
            }

            var checkType = registration.Type;
            var name      = registration.Name;

            if (TryGetValue(new DependencyContainer.TypeRegistration(checkType, name), out var factory))
            {
                if (factory.AssumeConstruction)
                {
                    return(true);
                }

                if (factory.Constructor == null)
                {
                    return(GetBestConstructor(factory.CreatesType, options) != null);
                }

                return(CanConstruct(factory.Constructor, options));
            }

            // Fail if requesting named resolution and settings set to fail if unresolved
            // Or bubble up if we have a parent
            if (!string.IsNullOrEmpty(name) && options.NamedResolutionFailureAction ==
                DependencyContainerNamedResolutionFailureAction.Fail)
            {
                return(_dependencyContainer.Parent?.RegisteredTypes.CanResolve(registration, options.Clone()) ?? false);
            }

            // Attempted unnamed fallback container resolution if relevant and requested
            if (!string.IsNullOrEmpty(name) && options.NamedResolutionFailureAction ==
                DependencyContainerNamedResolutionFailureAction.AttemptUnnamedResolution)
            {
                if (TryGetValue(new DependencyContainer.TypeRegistration(checkType), out factory))
                {
                    if (factory.AssumeConstruction)
                    {
                        return(true);
                    }

                    return(GetBestConstructor(factory.CreatesType, options) != null);
                }
            }

            // Check if type is an automatic lazy factory request or an IEnumerable<ResolveType>
            if (IsAutomaticLazyFactoryRequest(checkType) || registration.Type.IsIEnumerable())
            {
                return(true);
            }

            // Attempt unregistered construction if possible and requested
            // If we cant', bubble if we have a parent
            if ((options.UnregisteredResolutionAction ==
                 DependencyContainerUnregisteredResolutionAction.AttemptResolve) ||
                (checkType.IsGenericType && options.UnregisteredResolutionAction ==
                 DependencyContainerUnregisteredResolutionAction.GenericsOnly))
            {
                return((GetBestConstructor(checkType, options) != null) ||
                       (_dependencyContainer.Parent?.RegisteredTypes.CanResolve(registration, options.Clone()) ?? false));
            }

            // Bubble resolution up the container tree if we have a parent
            return(_dependencyContainer.Parent != null && _dependencyContainer.Parent.RegisteredTypes.CanResolve(registration, options.Clone()));
        }