大数跨境
0
0

给微软的依赖注入框架写一些扩展方法

给微软的依赖注入框架写一些扩展方法 amazingdotnet
2020-02-25
2
导读:让微软的依赖注入框架服务注册更简单

给微软的依赖注入框架写一些扩展方法

Intro

现在在项目里大多都是直接使用微软的依赖注入框架,而微软的注入方式比较简单,不如 AutoFac 使用起来灵活,于是想给微软的依赖注入增加一些扩展,使得可以像AutoFac 一样比较灵活的注册服务

Extensions

RegisterTypeAsImplementedInterface

将类型注册为其实现的接口,比如 pubicclassUserService:IUserService,IUserRepository{}

注册 UserServiceIUserServiceIUserRepository

等效于:

 
  1. services.AddSingleton<IUserService, UserService>();

  2. services.AddSingleton<IUserRepository, UserService>();

实现代码:

 
  1. /// <summary>

  2. /// RegisterTypeAsImplementedInterfaces

  3. /// </summary>

  4. /// <param name="services">services</param>

  5. /// <param name="type">type</param>

  6. /// <param name="serviceLifetime">service lifetime</param>

  7. /// <returns>services</returns>

  8. public static IServiceCollection RegisterTypeAsImplementedInterfaces(this IServiceCollection services, Type type, ServiceLifetime serviceLifetime = ServiceLifetime.Singleton)

  9. {

  10. if (type != null)

  11. {

  12. foreach (var interfaceType in type.GetImplementedInterfaces())

  13. {

  14. services.Add(new ServiceDescriptor(interfaceType, type, serviceLifetime));

  15. }

  16. }

  17. return services;

  18. }

RegisterAssemblyTypesAsImplementedInterface

在上面的基础上,加载指定程序集中的类型(不指定程序集则使用当前应用程序域中所有程序集),可以通过 typesFilter 来过滤要注册的类型

使用示例:

 
  1. services.RegisterAssemblyTypesAsImplementedInterface(t => !t.IsAbstract && t.IsClass && t.IsAssignableTo<IEventHandler>(), typeof(NoticeViewEventHandler).Assembly);

实现源码:

 
  1. /// <summary>

  2. /// RegisterTypeAsImplementedInterfaces

  3. /// </summary>

  4. /// <param name="services">services</param>

  5. /// <param name="assemblies">assemblies</param>

  6. /// <returns>services</returns>

  7. public static IServiceCollection RegisterAssemblyTypesAsImplementedInterfaces(this IServiceCollection services,

  8. params Assembly[] assemblies)

  9. => RegisterAssemblyTypesAsImplementedInterfaces(services, typesFilter: null, ServiceLifetime.Singleton, assemblies);


  10. /// <summary>

  11. /// RegisterTypeAsImplementedInterfaces

  12. /// </summary>

  13. /// <param name="services">services</param>

  14. /// <param name="serviceLifetime">service lifetime</param>

  15. /// <param name="assemblies">assemblies</param>

  16. /// <returns>services</returns>

  17. public static IServiceCollection RegisterAssemblyTypesAsImplementedInterfaces(this IServiceCollection services,

  18. ServiceLifetime serviceLifetime, params Assembly[] assemblies)

  19. => RegisterAssemblyTypesAsImplementedInterfaces(services, typesFilter: null, serviceLifetime, assemblies);


  20. /// <summary>

  21. /// RegisterTypeAsImplementedInterfaces, singleton by default

  22. /// </summary>

  23. /// <param name="services">services</param>

  24. /// <param name="typesFilter">filter types to register</param>

  25. /// <param name="assemblies">assemblies</param>

  26. /// <returns>services</returns>

  27. public static IServiceCollection RegisterAssemblyTypesAsImplementedInterfaces(this IServiceCollection services, Func<Type, bool> typesFilter, params Assembly[] assemblies)

  28. => RegisterAssemblyTypesAsImplementedInterfaces(services, typesFilter: typesFilter, ServiceLifetime.Singleton, assemblies);


  29. /// <summary>

  30. /// RegisterTypeAsImplementedInterfaces

  31. /// </summary>

  32. /// <param name="services">services</param>

  33. /// <param name="typesFilter">filter types to register</param>

  34. /// <param name="serviceLifetime">service lifetime</param>

  35. /// <param name="assemblies">assemblies</param>

  36. /// <returns>services</returns>

  37. public static IServiceCollection RegisterAssemblyTypesAsImplementedInterfaces(this IServiceCollection services, Func<Type, bool> typesFilter, ServiceLifetime serviceLifetime, params Assembly[] assemblies)

  38. {

  39. if (assemblies == null || assemblies.Length == 0)

  40. {

  41. assemblies = ReflectHelper.GetAssemblies();

  42. }


  43. var types = assemblies

  44. .Select(assembly => assembly.GetExportedTypes())

  45. .SelectMany(t => t);

  46. if (typesFilter != null)

  47. {

  48. types = types.Where(typesFilter);

  49. }


  50. foreach (var type in types)

  51. {

  52. foreach (var implementedInterface in type.GetImplementedInterfaces())

  53. {

  54. services.Add(new ServiceDescriptor(implementedInterface, type, serviceLifetime));

  55. }

  56. }


  57. return services;

  58. }

RegisterAssemblyTypes

注册类型,这相当于 AutoFacRegisterAssemblyTypes().AsSelf()

 
  1. services.RegisterAssemblyTypes(t => !t.IsAbstract && t.IsClass && t.IsAssignableTo<IEventHandler>(), typeof(NoticeViewEventHandler).Assembly);

实现源码:

 
  1. /// <summary>

  2. /// RegisterAssemblyTypes

  3. /// </summary>

  4. /// <param name="services">services</param>

  5. /// <param name="assemblies">assemblies</param>

  6. /// <returns>services</returns>

  7. public static IServiceCollection RegisterAssemblyTypes(this IServiceCollection services, params Assembly[] assemblies)

  8. => RegisterAssemblyTypes(services, null, ServiceLifetime.Singleton, assemblies);


  9. /// <summary>

  10. /// RegisterAssemblyTypes

  11. /// </summary>

  12. /// <param name="services">services</param>

  13. /// <param name="serviceLifetime">service lifetime</param>

  14. /// <param name="assemblies">assemblies</param>

  15. /// <returns>services</returns>

  16. public static IServiceCollection RegisterAssemblyTypes(this IServiceCollection services,

  17. ServiceLifetime serviceLifetime, params Assembly[] assemblies)

  18. => RegisterAssemblyTypes(services, null, serviceLifetime, assemblies);


  19. /// <summary>

  20. /// RegisterAssemblyTypes

  21. /// </summary>

  22. /// <param name="services">services</param>

  23. /// <param name="typesFilter">filter types to register</param>

  24. /// <param name="assemblies">assemblies</param>

  25. /// <returns>services</returns>

  26. public static IServiceCollection RegisterAssemblyTypes(this IServiceCollection services,

  27. Func<Type, bool> typesFilter, params Assembly[] assemblies)

  28. => RegisterAssemblyTypes(services, typesFilter, ServiceLifetime.Singleton, assemblies);


  29. /// <summary>

  30. /// RegisterAssemblyTypes

  31. /// </summary>

  32. /// <param name="services">services</param>

  33. /// <param name="typesFilter">filter types to register</param>

  34. /// <param name="serviceLifetime">service lifetime</param>

  35. /// <param name="assemblies">assemblies</param>

  36. /// <returns>services</returns>

  37. public static IServiceCollection RegisterAssemblyTypes(this IServiceCollection services, Func<Type, bool> typesFilter, ServiceLifetime serviceLifetime, params Assembly[] assemblies)

  38. {

  39. if (assemblies == null || assemblies.Length == 0)

  40. {

  41. assemblies = ReflectHelper.GetAssemblies();

  42. }


  43. var types = assemblies

  44. .Select(assembly => assembly.GetExportedTypes())

  45. .SelectMany(t => t);

  46. if (typesFilter != null)

  47. {

  48. types = types.Where(typesFilter);

  49. }


  50. foreach (var type in types)

  51. {

  52. services.Add(new ServiceDescriptor(type, type, serviceLifetime));

  53. }


  54. return services;

  55. }

ServiceModule

在 AutoFac 中有一个 Module 的概念可以让我们更方便的注册,一般可以在一个 Module 里注册需要服务注册的服务,这样注册的好处在于容易做插件化,新的插件需要注册什么样的服务,外界并不知道,如果用 Module 的注册方式,我只需要调用插件中的 Module 就可以注册所需要的服务了

IServiceModule

类似于 AutoFac 中的 Module,我们也可以定义一个 IServiceModule,定义一个 ConfigueServices(IServiceCollectionservices) 的方法用来注册服务

 
  1. public interface IServiceModule

  2. {

  3. void ConfigureServices(IServiceCollection services);

  4. }

ServiceModule Demo

 
  1. public class BusinessServiceModule : IServiceModule

  2. {

  3. public void ConfigureServices(IServiceCollection services)

  4. {

  5. services.AddEFRepository();

  6. services.AddBLL();

  7. services.TryAddScoped<ReservationHelper>();

  8. services.TryAddSingleton<CaptchaVerifyHelper>();

  9. services.TryAddSingleton<OperLogHelper>();

  10. }

  11. }

RegisterAssemblyModules

上面我们定义了一个 Module,下面来定义一个扩展方法来注册 module 中的服务信息

使用示例:

 
  1. // load service modules

  2. services.RegisterAssemblyModules(pluginAssemblies);

实现源码:

 
  1. /// <summary>

  2. /// RegisterAssemblyModules

  3. /// </summary>

  4. /// <param name="services">services</param>

  5. /// <param name="assemblies">assemblies</param>

  6. /// <returns>services</returns>

  7. public static IServiceCollection RegisterAssemblyModules(

  8. [NotNull] this IServiceCollection services, params Assembly[] assemblies)

  9. {

  10. if (assemblies == null || assemblies.Length == 0)

  11. {

  12. assemblies = ReflectHelper.GetAssemblies();

  13. }

  14. foreach (var type in assemblies.SelectMany(ass => ass.GetTypes())

  15. .Where(t => t.IsClass && !t.IsAbstract && typeof(IServiceModule).IsAssignableFrom(t))

  16. )

  17. {

  18. try

  19. {

  20. if (Activator.CreateInstance(type) is IServiceModule module)

  21. {

  22. module.ConfigureServices(services);

  23. }

  24. }

  25. catch (Exception e)

  26. {

  27. Console.WriteLine(e);

  28. }

  29. }


  30. return services;

  31. }

Reference

  • https://github.com/WeihanLi/WeihanLi.Common/blob/58cec5fe93baa3ad73df6e339e2fcb609a7b4b79/src/WeihanLi.Common/Extensions/ServiceCollectionExtension.cs

  • https://github.com/WeihanLi/ActivityReservation/blob/dev/ActivityReservation/Startup.cs

  • https://github.com/WeihanLi/ActivityReservation/blob/dev/ActivityReservation.Helper/Services/BusinessServiceModule.cs

  • https://github.com/WeihanLi/DbTool/blob/wpf-dev/DbTool/App.xaml.cs

  • https://autofac.readthedocs.io/en/latest/configuration/modules.html


【声明】内容源于网络
0
0
amazingdotnet
dotnet 开发知识库,了不起的 dotnet,dotnet 奇淫怪巧
内容 539
粉丝 0
amazingdotnet dotnet 开发知识库,了不起的 dotnet,dotnet 奇淫怪巧
总阅读212
粉丝0
内容539