/// <inheritdoc /> /// <summary> /// Finds the most appropriate type or subtype of /// <typeparamref name="TProvider" /> whose type name is <paramref name="providerName" /> /// or which has been decorated with a <see cref="T:Platibus.Config.Extensibility.ProviderAttribute" /> with the /// specified <paramref name="providerName" />. /// </summary> /// <typeparam name="TProvider">The provider type or at type from which the provider /// must inherit</typeparam> /// <param name="providerName">The provider name associated with the type</param> /// <returns>Returns a new provider instance with the specified /// <paramref name="providerName" /> and type.</returns> /// <exception cref="T:System.NullReferenceException">Thrown if <paramref name="providerName" /> /// is <c>null</c> or whitespace.</exception> /// <exception cref="T:Platibus.Config.Extensibility.ProviderNotFoundException">Thrown if no suitable providers are /// found in the application domain.</exception> /// <exception cref="T:Platibus.Config.Extensibility.MultipleProvidersFoundException">Thrown if there are multiple /// providers found with the same priority.</exception> /// <seealso cref="T:Platibus.Config.Extensibility.ProviderAttribute" /> public TProvider GetProvider <TProvider>(string providerName) { var providerType = Type.GetType(providerName); if (providerType == null) { var prioritizedProviders = _reflectionService .FindConcreteSubtypes <TProvider>() .Where(t => !t.IsGenericTypeDefinition) .WithProviderName(providerName) .GroupByPriorityDescending() .ToList(); var highestPriority = prioritizedProviders.FirstOrDefault(); if (highestPriority == null) { throw new ProviderNotFoundException(providerName); } var providers = highestPriority.ToList(); if (providers.Count > 1) { throw new MultipleProvidersFoundException(providerName, providers); } providerType = providers.First(); } return((TProvider)Activator.CreateInstance(providerType)); }