Last active
July 8, 2021 10:23
-
-
Save flq/a4ee6064cec34adbf08632796fd75904 to your computer and use it in GitHub Desktop.
Utility classes for named dependencies (,NET Core, C# 9)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Linq; | |
using System.Reflection; | |
using Microsoft.Extensions.DependencyInjection; | |
namespace DIPlaygroundWebApp.ServiceCollectionInfrastructure | |
{ | |
public static class AssemblyPoolRegistrar | |
{ | |
public static AssembliesForRegistration UseBulkRegistration(this IServiceCollection svcCollection, | |
params Assembly[] assemblies) => | |
new(svcCollection, assemblies); | |
public class AssembliesForRegistration | |
{ | |
private readonly Assembly[] _assemblies; | |
private readonly IServiceCollection _svcCollection; | |
public AssembliesForRegistration(IServiceCollection svcCollection, params Assembly[] assemblies) | |
{ | |
_svcCollection = svcCollection; | |
_assemblies = assemblies; | |
} | |
public AssembliesForRegistration AddAllTypesOf<T>(ServiceLifetime lifeTime = ServiceLifetime.Transient, | |
Func<TypeInfo, string> naming = null) | |
{ | |
var candidates = _assemblies.SelectMany(a => a.DefinedTypes) | |
.Where(t => t.InstantiableAndImplementing<T>()) | |
.ToList(); | |
var targetType = typeof(T); | |
foreach (var candidate in candidates) | |
_svcCollection.Add(new ServiceDescriptor(targetType, candidate, lifeTime)); | |
if (naming == null) return this; | |
var namingDictionary = candidates.ToDictionary(naming); | |
NamedLookupInfo.RegisterMap(targetType, namingDictionary); | |
// register all concrete types | |
foreach (var implementationType in namingDictionary.Values) | |
_svcCollection.Add(new ServiceDescriptor(implementationType, implementationType, lifeTime)); | |
_svcCollection.Add(new ServiceDescriptor(typeof(INamedLookup<T>), typeof(NamedLookup<T>), lifeTime)); | |
return this; | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Reflection; | |
namespace DIPlaygroundWebApp.ServiceCollectionInfrastructure | |
{ | |
public interface INamedLookup<out T> | |
{ | |
T this[string name] { get; } | |
} | |
public class NamedLookup<T> : INamedLookup<T> | |
{ | |
private readonly IReadOnlyDictionary<string, TypeInfo> _serviceMap; | |
private readonly IServiceProvider _serviceProvider; | |
public NamedLookup(IServiceProvider serviceProvider) | |
{ | |
_serviceProvider = serviceProvider; | |
if (!NamedLookupInfo.TryGetValue(typeof(T), out _serviceMap)) | |
throw new ArgumentException($"There is no service map for return type {typeof(T).Name} registered"); | |
} | |
public T this[string name] => _serviceMap.TryGetValue(name, out var serviceType) | |
? (T) _serviceProvider.GetService(serviceType) | |
: default; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Reflection; | |
namespace DIPlaygroundWebApp.ServiceCollectionInfrastructure | |
{ | |
public static class NamedLookupInfo | |
{ | |
private static readonly Dictionary<Type, IReadOnlyDictionary<string, TypeInfo>> ServiceMaps = new(); | |
public static void RegisterMap(Type serviceType, Dictionary<string, TypeInfo> serviceMap) | |
{ | |
ServiceMaps.Add(serviceType, serviceMap); | |
} | |
public static bool TryGetValue(Type serviceType, out IReadOnlyDictionary<string, TypeInfo> serviceMap) | |
{ | |
return ServiceMaps.TryGetValue(serviceType, out serviceMap); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Linq; | |
using System.Reflection; | |
namespace DIPlaygroundWebApp.ServiceCollectionInfrastructure | |
{ | |
public static class ReflectionExtensions | |
{ | |
public static bool InstantiableAndImplementing<TInterface>(this TypeInfo typeInfo) | |
{ | |
return !typeInfo.IsAbstract && typeInfo.ImplementedInterfaces.Contains(typeof(TInterface)); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment