经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » ASP.net » 查看文章
.NET6.0实现IOC容器
来源:cnblogs  作者:宣君  时间:2023/9/6 10:54:51  对本文有异议

.NET6.0实现IOC容器

IOC的作用这里省略…只对如何使用进行说明。

1. 创建一个.NET6应用程序

这里使用 .NET6.0 WebAPI 应用

2. 声明接口

  1. public interface IAuthService
  2. {
  3. bool CheckToken();
  4. }

3. 实现接口

  1. class AuthServiceImpl : IAuthService
  2. {
  3. public bool CheckToken()
  4. {
  5. Console.WriteLine("check token");
  6. return true;
  7. }
  8. }

4. 配置IOC容器

下面是在 program 类中的代码

  1. var services = new ServiceCollection();
  2. services.AddSingleton<IAuthService, AuthServiceImpl>();

5. 获取服务

通过在 Controller的构造函数中注入IAuthService

  1. private readonly IAuthService _service;
  2. public WeatherForecastController(IAuthService service)
  3. {
  4. _service = service;
  5. }
  6. [HttpGet(Name = "test")]
  7. public bool Get()
  8. {
  9. return _service.CheckToken();
  10. }

启动后,通过swagger发起请求,验证接口。

基本IOC容器流程已实现。但是这样存在一个弊端,每个接口和实现都要在program中手动注册一遍,还要在Controller构造函数中进行依赖注入,有没有能自动实现注册代替program中的手动注册?

接下来,对上述流程进行改良。

6. 改良思路

定义一个AutowiredAttribute标记,通过Atrribute标记的方式,在实现类上标记其要实现的接口服务,然后实现一个服务加载类ServiceLoader,在这个类中反射获取所有具备AutoIocAttribute的实现类,然后注册到ServiceCollection中。

6.1 定义特性标记AutowiredAttribute

  1. [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
  2. public class AutowiredAttribute : Attribute
  3. {
  4. /// <summary>
  5. /// 接口
  6. /// </summary>
  7. public Type Iface { get; set; }
  8. /// <summary>
  9. /// 实现类名
  10. /// </summary>
  11. public string ImplClassName { get; set; }
  12. public AutowiredAttribute(Type iface, [CallerMemberName] string implClassName = "")
  13. {
  14. Iface = iface;
  15. ImplClassName = implClassName;
  16. }
  17. }

6.2 实现服务加载类

利用IServiceCollection作为服务容器

  1. public class ServiceLoader
  2. {
  3. private static object _lock = new object();
  4. private static AppRuntime _inst;
  5. private readonly IServiceCollection _iocService = new ServiceCollection();
  6. private readonly ICollection<Assembly> _iocAssembly = new HashSet<Assembly>();
  7. private IServiceProvider _iocServiceProvider = null;
  8. public static ServiceLoader Instance
  9. {
  10. get
  11. {
  12. if (_inst == null)
  13. {
  14. lock (_lock)
  15. {
  16. _inst = new ServiceLoader();
  17. _inst.Startup(typeof(ServiceLoader).Assembly);
  18. }
  19. }
  20. return _inst;
  21. }
  22. }
  23. public T GetService<T>()
  24. {
  25. EnsureAutoIoc<T>();
  26. return _iocServiceProvider.GetService<T>();
  27. }
  28. private void EnsureAutoIoc<T>()
  29. {
  30. Startup(typeof(T).Assembly);
  31. }
  32. public void Startup(Assembly ass)
  33. {
  34. if (_iocAssembly.Any(x => x == ass))
  35. {
  36. return;
  37. }
  38. _iocAssembly.Add(ass);
  39. var types = ass.GetTypes().Where(x => x.GetCustomAttribute<AutowiredAttribute>() != null);
  40. foreach (var item in types)
  41. {
  42. var autoIocAtt = item.GetCustomAttribute<AutowiredAttribute>();
  43. AddTransient(autoIocAtt.Iface, item);
  44. }
  45. //_iocServiceProvider = _iocService.BuildServiceProvider();
  46. Interlocked.Exchange(ref _iocServiceProvider, _iocService.BuildServiceProvider());
  47. }
  48. private void AddTransient(Type iface, Type impl)
  49. {
  50. _iocService.AddTransient(iface, impl);
  51. }
  52. }

6.3 在实现类加上标记

  1. [Autowired(typeof(IAuthService))]
  2. class AuthServiceImpl : IAuthService
  3. {
  4. public bool CheckToken()
  5. {
  6. Console.WriteLine("check token");
  7. return true;
  8. }
  9. }

6.4 在 Controller 中调用

  1. var svc = ServiceLoader.Instance.GetService<IAuthService>();
  2. svc.CheckToken();

至此一个基本的完整IOC容器已实现。

原文链接:https://www.cnblogs.com/ycit/p/17680238.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号