ServiceCollectionExtensions.cs 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. using System;
  2. using System.Linq;
  3. using System.Reflection;
  4. using Microsoft.Extensions.DependencyInjection;
  5. namespace ZhonTai.Tools.DynamicApi.Helpers
  6. {
  7. internal static class ServiceCollectionExtensions
  8. {
  9. public static bool IsAdded<T>(this IServiceCollection services)
  10. {
  11. return services.IsAdded(typeof(T));
  12. }
  13. public static bool IsAdded(this IServiceCollection services, Type type)
  14. {
  15. return services.Any(d => d.ServiceType == type);
  16. }
  17. public static T GetSingletonInstanceOrNull<T>(this IServiceCollection services)
  18. {
  19. return (T)services
  20. .FirstOrDefault(d => d.ServiceType == typeof(T))
  21. ?.ImplementationInstance;
  22. }
  23. public static T GetSingletonInstance<T>(this IServiceCollection services)
  24. {
  25. var service = services.GetSingletonInstanceOrNull<T>();
  26. if (service == null)
  27. {
  28. throw new InvalidOperationException("Could not find singleton service: " + typeof(T).AssemblyQualifiedName);
  29. }
  30. return service;
  31. }
  32. public static IServiceProvider BuildServiceProviderFromFactory(this IServiceCollection services)
  33. {
  34. foreach (var service in services)
  35. {
  36. var factoryInterface = service.ImplementationInstance?.GetType()
  37. .GetTypeInfo()
  38. .GetInterfaces()
  39. .FirstOrDefault(i => i.GetTypeInfo().IsGenericType &&
  40. i.GetGenericTypeDefinition() == typeof(IServiceProviderFactory<>));
  41. if (factoryInterface == null)
  42. {
  43. continue;
  44. }
  45. var containerBuilderType = factoryInterface.GenericTypeArguments[0];
  46. return (IServiceProvider)typeof(ServiceCollectionExtensions)
  47. .GetTypeInfo()
  48. .GetMethods()
  49. .Single(m => m.Name == nameof(BuildServiceProviderFromFactory) && m.IsGenericMethod)
  50. .MakeGenericMethod(containerBuilderType)
  51. .Invoke(null, new object[] { services, null });
  52. }
  53. return services.BuildServiceProvider();
  54. }
  55. public static IServiceProvider BuildServiceProviderFromFactory<TContainerBuilder>(this IServiceCollection services, Action<TContainerBuilder> builderAction = null)
  56. {
  57. var serviceProviderFactory = services.GetSingletonInstanceOrNull<IServiceProviderFactory<TContainerBuilder>>();
  58. if (serviceProviderFactory == null)
  59. {
  60. throw new Exception($"Could not find {typeof(IServiceProviderFactory<TContainerBuilder>).FullName} in {services}.");
  61. }
  62. var builder = serviceProviderFactory.CreateBuilder(services);
  63. builderAction?.Invoke(builder);
  64. return serviceProviderFactory.CreateServiceProvider(builder);
  65. }
  66. }
  67. }