/// <summary> /// Method that will actually resolve the instances. /// </summary> /// <typeparam name="TInstance">The type of the instances we want.</typeparam> /// <returns> /// Returns a list with <see cref="TInstance"/> instances. /// The list could be empty when no implementations were found. /// </returns> public List <TInstance> ResolveInstances <TInstance>(bool onlyLookInPlugins = true) { // get the type once, instead of once every type. IsOfType typeCheckMethod = IsSubclassOf; var typeOfTInstance = typeof(TInstance); if (typeOfTInstance.IsInterface) { typeCheckMethod = ImplementsInterface; } var returnList = new List <TInstance>(); var assemblies = getAssemblyCollection(onlyLookInPlugins); if (assemblies.Count == 0) { LogUtility.Out("[SK] InstanceResolver: No assemblies found."); return(returnList); } foreach (var assembly in assemblies) { LogUtility.Out("[SK] InstanceResolver: Scanning assembly " + assembly.Location); // loop all assemblies, see if it contains types we are looking for. Type[] typesInAssembly = new Type[0]; try { typesInAssembly = assembly.GetTypes(); } catch (Exception exception) { // Not yet able to cover this piece of code with a unit test. var survivalKitException = new SurvivalKit.Exceptions.SurvivalKitPluginException("SK.ResolveInstances", "SurvivalKit.Utility.InstanceResolver", "Unable to extract types from assembly: " + assembly.FullName, exception); LogUtility.Exception(survivalKitException); } foreach (var typeInAssembly in typesInAssembly) { if (typeInAssembly.IsInterface || typeInAssembly.IsAbstract) { continue; } // loop all types in the assembly. only act when it matches our needs. if (typeCheckMethod(typeInAssembly, typeOfTInstance)) { var constructors = typeInAssembly.GetConstructors(); var foundValidConstructor = false; foreach (var item in constructors) { if (item.GetParameters().Length == 0) { foundValidConstructor = true; } } if (!foundValidConstructor) { // there is no constructor without arguments, we can't instantiate those (yet?) continue; } try { var instance = (TInstance)Activator.CreateInstance(typeInAssembly); returnList.Add(instance); } catch (Exception exception) { var wrappedException = new SurvivalKitPluginException("ResolvePlugin", "SurvivalKit.InstanceResolver.ResolveInstances", "Error while invoking constructor", exception); LogUtility.Exception(wrappedException); } } } } return(returnList); }