Example #1
0
        /// <summary>
        /// Gets a new instance for the given root key. If the key is an interface, the mapped interfaces will be searched for an implementation. If the key is a type, it will be constructed with all resolvable interfaces.
        /// </summary>
        /// <param name="root">The root key (interface or class) to be constructed</param>
        /// <returns>A constructed instance of the type indicated by the key</returns>
        public static object GetNewInstance(Type root)
        {
            Type implementation;

            if (root.IsInterface)
            {
                EnsureTypeIsResolvable(root);

                // Whilst we do support injecting an array of dependencies into an implementation, supplying a root which has multiple implementations to GetNewInstance is not valid, as we don't know which one to return.

                var types = ResolvableInterfaces.GetTypes(root);

                if (types.Count > 1)
                {
                    throw IoCValidateException.NewMultipleImplementationsFoundException(root);
                }

                // if we don't have any types relating directly to the interface, we might still about to construct from a generic class
                implementation = types.Count == 0
                                ? ResolvableInterfaces.GetTypes(root.GetGenericTypeDefinition()).Single()
                                : types.Single();
            }
            else
            {
                implementation = root;
            }

            return(implementation.ContainsGenericParameters
                        ? ConstructGenericType(implementation, root.GenericTypeArguments)
                        : ConstructType(implementation));
        }
Example #2
0
        /// <summary>
        /// Gets a known constructed implementationfor the given root key. Repeated calls to this method will return the same instance.
        /// </summary>
        /// <param name="root">The root key to be constructed (this should be an interface)</param>
        /// <returns>A constructed instance of the type indicated by the key</returns>
        public static object GetInstance(Type root)
        {
            lock (ConstructedInstances)
            {
                // If we have an interface, resolve it and create a new instance
                if (root.GetTypeInfo().IsInterface || root.GetTypeInfo().IsArray&& (root.GetTypeInfo().GetElementType()?.IsInterface ?? false))
                {
                    if (!ConstructedInstances.ContainsKey(root))
                    {
                        MapConstructedInstance(root, GetNewInstance(root));
                    }

                    return(ConstructedInstances[root].SingleOrDefault() ?? throw IoCValidateException.NewMultipleImplementationsFoundException(root));
                }

                // If it isn't an interface but we have it anyway, fish out the instance
                if (ConstructedInstances.ContainsKey(root))
                {
                    return(ConstructedInstances[root].SingleOrDefault() ?? throw IoCValidateException.NewMultipleImplementationsFoundException(root));
                }

                // If we don't have the type in the dictionary keys, look through the values and return the first one we find.
                foreach (object constructedInstance in ConstructedInstances.SelectMany(x => x.Value))
                {
                    if (constructedInstance.GetType() == root)
                    {
                        return(constructedInstance);
                    }
                }

                // We still haven't got an instance, create a new one
                object instance = GetNewInstance(root);

                // Add it, keyed by type (not interface)
                ConstructedInstances.Add(root, new List <object>()
                {
                    instance
                });

                return(instance);
            }
        }