请选择 进入手机版 | 继续访问电脑版

马上加入IBC程序猿 各种源码随意下,各种教程随便看! 注册 每日签到 加入编程讨论群

C#教程 ASP.NET教程 C#视频教程程序源码享受不尽 C#问题入口 ASP.NET问题入口

【C#问题提交】 社群合作 申请版主 程序开发 【远程协助】 每天乐一乐 每日签到 【承接毕业设计】 面试-葵花宝典下载

官方一群:

官方二群:

查看: 72|回复: 0

ASP.NET Core 3.0 原生DI拓展实现IocManager

[复制链接]
  • TA的每日心情
    开心
    13 小时前
  • 签到天数: 1486 天

    [LV.10]以坛为家III

    1541

    主题

    3452

    帖子

    9万

    积分

    管理员

    IBC编程社区-原道楠

    Rank: 9Rank: 9Rank: 9

    积分
    96031

    推广达人突出贡献优秀版主荣誉管理论坛元老

    发表于 2019-9-26 09:21:34 | 显示全部楼层 |阅读模式

    马上加入IBC,查看更多教程

    您需要 登录 才可以下载或查看,没有帐号?立即注册

    x

    昨天.NET Core 3.0 正式发布,创建一个项目运行后发现:原来利用的Autofac在ConfigureServices返回IServiceProvider的这种写法已经不再支持。当然Autofac官方也给出了示例。

    .NET Core 自己内置DI,我决定不再利用Autofac,就利用原生DI,拓展IServiceCollection实现一个IocManager,

    实现批量注入,静态获取实例功能。

    一、Autofac官方文档

    Program Class

    Hosting changed in ASP.NET Core 3.0 and requires a slightly different integration. This is for ASP.NET Core 3+ and the .NET Core 3+ generic hosting support:

    1. <code>public class Program
    2. {
    3. public static void Main(string[] args)
    4. {
    5. // ASP.NET Core 3.0+:
    6. // The UseServiceProviderFactory call attaches the
    7. // Autofac provider to the generic hosting mechanism.
    8. var host = Host.CreateDefaultBuilder(args)
    9. .UseServiceProviderFactory(new AutofacServiceProviderFactory())
    10. .ConfigureWebHostDefaults(webHostBuilder => {
    11. webHostBuilder
    12. .UseContentRoot(Directory.GetCurrentDirectory())
    13. .UseIISIntegration()
    14. .UseStartup<Startup>();
    15. })
    16. .Build();
    17. host.Run();
    18. }
    19. }</code>
    复制代码

    Startup Class

    In your Startup class (which is basically the same across all the versions of ASP.NET Core) you then use ConfigureContainer to access the Autofac container builder and register things directly with Autofac.

    1. <code>public class Startup
    2. {
    3. public Startup(IHostingEnvironment env)
    4. {
    5. // In ASP.NET Core 3.0 env will be an IWebHostingEnvironment, not IHostingEnvironment.
    6. var builder = new ConfigurationBuilder()
    7. .SetBasePath(env.ContentRootPath)
    8. .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
    9. .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
    10. .AddEnvironmentVariables();
    11. this.Configuration = builder.Build();
    12. }
    13. public IConfigurationRoot Configuration { get; private set; }
    14. public ILifetimeScope AutofacContainer { get; private set; }
    15. // ConfigureServices is where you register dependencies. This gets
    16. // called by the runtime before the ConfigureContainer method, below.
    17. public void ConfigureServices(IServiceCollection services)
    18. {
    19. // Add services to the collection. Don&#39;t build or return
    20. // any IServiceProvider or the ConfigureContainer method
    21. // won&#39;t get called.
    22. services.AddOptions();
    23. }
    24. // ConfigureContainer is where you can register things directly
    25. // with Autofac. This runs after ConfigureServices so the things
    26. // here will override registrations made in ConfigureServices.
    27. // Don&#39;t build the container; that gets done for you. If you
    28. // need a reference to the container, you need to use the
    29. // "Without ConfigureContainer" mechanism shown later.
    30. public void ConfigureContainer(ContainerBuilder builder)
    31. {
    32. builder.RegisterModule(new AutofacModule());
    33. }
    34. // Configure is where you add middleware. This is called after
    35. // ConfigureContainer. You can use IApplicationBuilder.ApplicationServices
    36. // here if you need to resolve things from the container.
    37. public void Configure(
    38. IApplicationBuilder app,
    39. ILoggerFactory loggerFactory)
    40. {
    41. // If, for some reason, you need a reference to the built container, you
    42. // can use the convenience extension method GetAutofacRoot.
    43. this.AutofacContainer = app.ApplicationServices.GetAutofacRoot();
    44. loggerFactory.AddConsole(this.Configuration.GetSection("Logging"));
    45. loggerFactory.AddDebug();
    46. app.UseMvc();
    47. }
    48. }</code>
    复制代码

    二、IocManager实现

    1、创建IocManager

    1. <code>public interface IIocManager
    2. {
    3. IServiceProvider ServiceProvider { get; set; }
    4. }</code>
    复制代码
    1. <code>public class IocManager : IIocManager
    2. {
    3. static IocManager()
    4. {
    5. Instance = new IocManager();
    6. }
    7. public static IocManager Instance { get; private set; }
    8. public IServiceProvider ServiceProvider { get; set; }
    9. }</code>
    复制代码

    2、创建生命周期接口

    1. <code> /// <summary>
    2. /// 标记依赖项生命周期的接口
    3. /// <see cref="ILifetimeScopeDependency" />,
    4. /// <see cref="ITransientDependency" />,
    5. /// <see cref="ISingletonDependency" />
    6. /// </summary>
    7. public interface ILifetime { }
    8. /// <summary>
    9. /// 确定接口或类的生存期
    10. /// 作用域模式,服务在每次哀求时被创建,整个哀求过程中都贯穿利用这个创建的服务。
    11. /// </summary>
    12. public interface ILifetimeScopeDependency : ILifetime { }
    13. /// <summary>
    14. /// 确定接口或类的生存期
    15. /// 作用域模式,服务在每次哀求时被创建,整个哀求过程中都贯穿利用这个创建的服务。
    16. /// </summary>
    17. public interface ILifetimeScopeDependency : ILifetime { }
    18. /// <summary>
    19. /// 确定接口或类的生存期
    20. /// 瞬态模式,每次哀求时都会创建。
    21. /// </summary>
    22. public interface ITransientDependency : ILifetime { }</code>
    复制代码

    3、拓展IServiceCollection

    1. <code>/// <summary>
    2. /// .NET Core 依赖注入拓展
    3. /// </summary>
    4. public static class DependencyInjectionExtensions
    5. {
    6. /// <summary>
    7. /// 注册步伐集组件
    8. /// </summary>
    9. /// <param name="services"></param>
    10. /// <param name="assemblies"></param>
    11. /// <returns></returns>
    12. public static IServiceCollection AddAssembly(this IServiceCollection services, params Assembly[] assemblies)
    13. {
    14. if (assemblies==null||assemblies.Count()==0)
    15. {
    16. throw new Exception("assemblies cannot be empty.");
    17. }
    18. foreach (var assembly in assemblies)
    19. {
    20. RegisterDependenciesByAssembly<ISingletonDependency>(services, assembly);
    21. RegisterDependenciesByAssembly<ITransientDependency>(services, assembly);
    22. RegisterDependenciesByAssembly<ILifetimeScopeDependency>(services, assembly);
    23. }
    24. return services;
    25. }
    26. public static void RegisterDependenciesByAssembly<TServiceLifetime>(IServiceCollection services, Assembly assembly)
    27. {
    28. var types = assembly.GetTypes().Where(x => typeof(TServiceLifetime).GetTypeInfo().IsAssignableFrom(x) && x.GetTypeInfo().IsClass && !x.GetTypeInfo().IsAbstract && !x.GetTypeInfo().IsSealed).ToList();
    29. foreach (var type in types)
    30. {
    31. var itype = type.GetTypeInfo().GetInterfaces().FirstOrDefault(x => x.Name.ToUpper().Contains(type.Name.ToUpper()));
    32. if (itype!=null)
    33. {
    34. var serviceLifetime = FindServiceLifetime(typeof(TServiceLifetime));
    35. services.Add(new ServiceDescriptor(itype, type, serviceLifetime));
    36. }
    37. }
    38. }
    39. private static ServiceLifetime FindServiceLifetime(Type type)
    40. {
    41. if (type == typeof(ISingletonDependency))
    42. {
    43. return ServiceLifetime.Singleton;
    44. }
    45. if (type == typeof(ITransientDependency))
    46. {
    47. return ServiceLifetime.Singleton;
    48. }
    49. if (type == typeof(ILifetimeScopeDependency))
    50. {
    51. return ServiceLifetime.Singleton;
    52. }
    53. throw new ArgumentOutOfRangeException($"Provided ServiceLifetime type is invalid. Lifetime:{type.Name}");
    54. }
    55. /// <summary>
    56. /// 注册IocManager
    57. /// 在ConfigureServices方法最后一行利用
    58. /// </summary>
    59. /// <param name="services"></param>
    60. public static void AddIocManager(this IServiceCollection services)
    61. {
    62. services.AddSingleton<IIocManager, IocManager>(provide =>
    63. {
    64. IocManager.Instance.ServiceProvider = provide;
    65. return IocManager.Instance;
    66. });
    67. }
    68. }</code>
    复制代码

    4、IocManager利用实例:

    4.1、示例步伐集

    1. <code>namespace Service
    2. {
    3. public interface IUserService
    4. {
    5. string GetUserNameById(string Id);
    6. }
    7. public interface UserService:IUserService,ISingletonDependency
    8. {
    9. public string GetUserNameById(string Id)
    10. {
    11. return "刘大大";
    12. }
    13. }
    14. }</code>
    复制代码

    4.2、为步伐集写一个拓展类

    1. <code>public static class ServiceExtensions
    2. {
    3. public static IServiceCollection UseService(this IServiceCollection services)
    4. {
    5. var assembly = typeof(ServiceExtensions).Assembly;
    6. services.AddAssembly(assembly);
    7. return services;
    8. }
    9. }</code>
    复制代码

    4.3、Web层利用

    Startup class
    1. <code> public void ConfigureServices(IServiceCollection services)
    2. {
    3. services.UseService();
    4. services.AddControllersWithViews();
    5. services.AddIocManager();
    6. }</code>
    复制代码
    Controller

    IIocManager实现了单例模式,可以通过构造器注入获取实例,也可以通过通过IocManager.Instance获取实例

    1. <code> public class HomeController : Controller
    2. {
    3. private readonly IIocManager _iocManager;
    4. public HomeController(IIocManager iocManager)
    5. {
    6. _iocManager = iocManager;
    7. }
    8. public string test1()
    9. {
    10. //通过注入获取IocManager实例
    11. var _userService=_iocManager.ServiceProvider.GetService<IUserService>();
    12. var userName=_userService.GetUserNameById("1");
    13. return userName;
    14. }
    15. public string test2()
    16. {
    17. //通过IocManager获取IIocManager实例
    18. var _userService=IocManager.Instance.ServiceProvider.GetService<IUserService>();
    19. var userName=_userService.GetUserNameById("1");
    20. return userName;
    21. }
    22. public string test3([FromServices]IUserService _userService)
    23. {
    24. //通过注入获取Service实例
    25. var userName=_userService.GetUserNameById("1");
    26. return userName;
    27. }
    28. }</code>
    复制代码

    092204ctc6tzq8pd9cpp9q.png







    来源:https://www.cnblogs.com/lwc1st/archive/2019/09/25/11582662.html
    C#论坛 www.ibcibc.com IBC编程社区
    C#
    C#论坛
    IBC编程社区
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则