翼度科技»论坛 编程开发 .net 查看内容

.NET6.0实现IOC容器

6

主题

6

帖子

18

积分

新手上路

Rank: 1

积分
18
.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.    
  5.         public bool CheckToken()
  6.         {
  7.             Console.WriteLine("check token");
  8.             return true;
  9.         }
  10.     }
复制代码
6.4 在 Controller 中调用
  1.    var svc = ServiceLoader.Instance.GetService<IAuthService>();
  2.    svc.CheckToken();
复制代码
至此一个基本的完整IOC容器已实现。

来源:https://www.cnblogs.com/ycit/archive/2023/09/05/17680238.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具