refactor: Move some of the dependency injection code to the Common Library.

This commit is contained in:
real-zony
2022-10-06 12:45:01 +08:00
parent aa90e232f7
commit ecab0e0f5c
34 changed files with 60 additions and 73 deletions

View File

@@ -0,0 +1,76 @@
using System.Reflection;
using Microsoft.Extensions.DependencyInjection;
using ZonyLrcTools.Common.Infrastructure.Extensions;
namespace ZonyLrcTools.Common.Infrastructure.DependencyInject
{
public static class AutoDependencyInjectExtensions
{
/// <summary>
/// 开始进行自动依赖注入。
/// </summary>
/// <remarks>
/// 会根据实现了 <see cref="ITransientDependency"/> 或 <see cref="ISingletonDependency"/> 的接口进行自动注入。
/// </remarks>
/// <param name="services">服务定义集合。</param>
/// <typeparam name="TAssemblyType">需要注入的任意类型。</typeparam>
public static IServiceCollection BeginAutoDependencyInject<TAssemblyType>(this IServiceCollection services)
{
var allTypes = typeof(TAssemblyType).Assembly
.GetTypes()
.Where(t => t.IsClass && !t.IsAbstract && !t.IsGenericType)
.ToArray();
var transientTypes = allTypes.Where(t => typeof(ITransientDependency).IsAssignableFrom(t));
var singletonTypes = allTypes.Where(t => typeof(ISingletonDependency).IsAssignableFrom(t));
transientTypes.Foreach(t =>
{
foreach (var exposedService in GetDefaultExposedTypes(t))
{
services.Add(CreateServiceDescriptor(t, exposedService, ServiceLifetime.Transient));
}
});
singletonTypes.Foreach(t =>
{
foreach (var exposedService in GetDefaultExposedTypes(t))
{
services.Add(CreateServiceDescriptor(t, exposedService, ServiceLifetime.Singleton));
}
});
return services;
}
public static List<Type> GetDefaultExposedTypes(Type type)
{
var serviceTypes = new List<Type>();
foreach (var interfaceType in type.GetTypeInfo().GetInterfaces())
{
var interfaceName = interfaceType.Name;
if (interfaceName.StartsWith("I"))
{
interfaceName = interfaceName.Substring(1, interfaceName.Length - 1);
}
if (type.Name.EndsWith(interfaceName))
{
serviceTypes.Add(interfaceType);
serviceTypes.Add(type);
}
}
return serviceTypes;
}
public static ServiceDescriptor CreateServiceDescriptor(Type implementationType,
Type exposingServiceType,
ServiceLifetime lifetime)
{
return new ServiceDescriptor(exposingServiceType, implementationType, lifetime);
}
}
}

View File

@@ -0,0 +1,9 @@
namespace ZonyLrcTools.Common.Infrastructure.DependencyInject
{
/// <summary>
/// 继承了本接口的类都会以单例的形式注入到 IoC 容器当中。
/// </summary>
public interface ISingletonDependency
{
}
}

View File

@@ -0,0 +1,9 @@
namespace ZonyLrcTools.Common.Infrastructure.DependencyInject
{
/// <summary>
/// 继承了本接口的类都会以瞬时的形式注入到 IoC 容器当中。
/// </summary>
public interface ITransientDependency
{
}
}

View File

@@ -0,0 +1,55 @@
using System.Net;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using ZonyLrcTools.Common.Configuration;
using ZonyLrcTools.Common.Infrastructure.Network;
namespace ZonyLrcTools.Common.Infrastructure.DependencyInject
{
/// <summary>
/// Service 注入的扩展方法。
/// </summary>
public static class ServiceCollectionExtensions
{
/// <summary>
/// 配置工具会用到的服务。
/// </summary>
public static IServiceCollection ConfigureToolService(this IServiceCollection services)
{
if (services == null)
{
return null;
}
services.AddHttpClient(DefaultWarpHttpClient.HttpClientNameConstant)
.ConfigurePrimaryHttpMessageHandler(provider =>
{
var option = provider.GetRequiredService<IOptions<GlobalOptions>>().Value;
return new HttpClientHandler
{
UseProxy = option.NetworkOptions.IsEnable,
Proxy = new WebProxy($"{option.NetworkOptions.Ip}:{option.NetworkOptions.Port}")
};
});
return services;
}
/// <summary>
/// 配置工具关联的配置信息(<see cref="IConfiguration"/>)。
/// </summary>
public static IServiceCollection ConfigureConfiguration(this IServiceCollection services)
{
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddYamlFile("config.yaml")
.Build();
services.Configure<GlobalOptions>(configuration.GetSection("globalOption"));
return services;
}
}
}