123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- using Microsoft.Extensions.Configuration;
- using Microsoft.Extensions.DependencyInjection;
- using System;
- using System.Linq;
- using System.Reflection;
- namespace FastGithub
- {
- /// <summary>
- /// 服务注册扩展
- /// </summary>
- public static class ServiceCollectionExtensions
- {
- /// <summary>
- /// 注册程序集下所有服务下选项
- /// </summary>
- /// <param name="services"></param>
- /// <param name="configuration">配置</param>
- /// <returns></returns>
- public static IServiceCollection AddServiceAndOptions(this IServiceCollection services, Assembly assembly, IConfiguration configuration)
- {
- services.AddAttributeServices(assembly);
- services.AddAttributeOptions(assembly, configuration);
- return services;
- }
- /// <summary>
- /// 添加程序集下ServiceAttribute标记的服务
- /// </summary>
- /// <param name="services"></param>
- /// <param name="assembly"></param>
- /// <returns></returns>
- private static IServiceCollection AddAttributeServices(this IServiceCollection services, Assembly assembly)
- {
- var implTypes = assembly
- .GetTypes()
- .Where(item => item.IsClass && item.IsAbstract == false)
- .ToArray();
- foreach (var implType in implTypes)
- {
- var attributes = implType.GetCustomAttributes<ServiceAttribute>(false);
- foreach (var attr in attributes)
- {
- var serviceType = attr.ServiceType ?? implType;
- if (services.Any(item => item.ServiceType == serviceType && item.ImplementationType == implType) == false)
- {
- var descriptor = ServiceDescriptor.Describe(serviceType, implType, attr.Lifetime);
- services.Add(descriptor);
- }
- }
- }
- return services;
- }
- /// <summary>
- /// 添加程序集下OptionsAttribute标记的服务
- /// </summary>
- /// <param name="services"></param>
- /// <param name="assembly"></param>
- /// <param name="configuration"></param>
- private static IServiceCollection AddAttributeOptions(this IServiceCollection services, Assembly assembly, IConfiguration configuration)
- {
- foreach (var optionsType in assembly.GetTypes())
- {
- var optionsAttribute = optionsType.GetCustomAttribute<OptionsAttribute>();
- if (optionsAttribute != null)
- {
- var key = optionsAttribute.SessionKey ?? optionsType.Name;
- var section = configuration.GetSection(key);
- OptionsBinder.Create(services, optionsType).Bind(section);
- }
- }
- return services;
- }
- /// <summary>
- /// options绑定器
- /// </summary>
- private abstract class OptionsBinder
- {
- public abstract void Bind(IConfiguration configuration);
- /// <summary>
- /// 创建OptionsBinder实例
- /// </summary>
- /// <param name="services"></param>
- /// <param name="optionsType"></param>
- /// <returns></returns>
- public static OptionsBinder Create(IServiceCollection services, Type optionsType)
- {
- var binderType = typeof(OptionsBinderImpl<>).MakeGenericType(optionsType);
- var binder = Activator.CreateInstance(binderType, new object[] { services });
- return binder is OptionsBinder optionsBinder
- ? optionsBinder
- : throw new TypeInitializationException(binderType.FullName, null);
- }
- private class OptionsBinderImpl<TOptions> : OptionsBinder where TOptions : class
- {
- private readonly IServiceCollection services;
- public OptionsBinderImpl(IServiceCollection services)
- {
- this.services = services;
- }
- public override void Bind(IConfiguration configuration)
- {
- this.services.AddOptions<TOptions>().Bind(configuration);
- }
- }
- }
- }
- }
|