/// <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)); }
/// <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); } }