1 Star 0 Fork 0

紫剑真人 / WebApi脚手架

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
InterfacesAsControllers.cs 4.71 KB
一键复制 编辑 原始数据 按行查看 历史
紫剑真人 提交于 2022-05-31 17:23 . 完善注释
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Security.Cryptography;
using System.Threading;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Primitives;
using zijian666.Core;
using zijian666.WebApi.Attributes;
namespace zijian666.WebApi
{
public partial class WebApiOptions
{
private readonly List<Type> _dynamicControllerTypes = new();
/// <summary>
/// 将指定接口添加为控制器
/// </summary>
public void AddInterfacesAsControllers(params Type[] interfaceTypes)
=> AddInterfacesAsControllers((IEnumerable<Type>)interfaceTypes);
/// <summary>
/// 将标记为 <seealso cref="HttpApiAttribute"/> 的接口添加为控制器
/// </summary>
public void AddInterfacesAsControllers()
=> AddInterfacesAsControllers(AssemblyResolver.Default.GetTypesWithAttribute<HttpApiAttribute>().Select(x => x.Item1));
/// <summary>
/// 将命名空间为 <paramref name="namespace"/> 的接口添加为控制器
/// </summary>
public void AddInterfacesAsControllers(string @namespace)
=> AddInterfacesAsControllers(AssemblyResolver.Default.GetTypesWithNamespace(@namespace, true));
/// <summary>
/// 将指定接口添加为控制器
/// </summary>
public void AddInterfacesAsControllers(IEnumerable<Type> interfaceTypes)
{
foreach (var type in interfaceTypes.Where(x => x.IsInterface))
{
var implementationType = AssemblyResolver.Default.GetTypesWithAssignableFrom(type).FirstOrDefault();
if (implementationType is not null)
{
_services.TryAddSingleton(type, implementationType);
}
_dynamicControllerTypes.Add(type);
}
InjectDynamicControllers();
}
private void InjectDynamicControllers()
{
_services.TryAddSingleton<DynamicControllersChangeProvider>();
_services.TryAddSingleton<IActionDescriptorChangeProvider>(p => p.GetRequiredService<DynamicControllersChangeProvider>());
AddConfigureHandler("DynamicControllers", app =>
{
if (_dynamicControllerTypes.Count > 0)
{
app.ApplicationServices.GetRequiredService<DynamicControllersChangeProvider>().InterfacesAsControllers(_dynamicControllerTypes);
_dynamicControllerTypes.Clear();
}
});
}
private class DynamicControllersChangeProvider : IActionDescriptorChangeProvider
{
public DynamicControllersChangeProvider(ApplicationPartManager applicationPartManager, ILogger<WebApiOptions> logger)
{
_applicationPartManager = applicationPartManager;
_logger = logger;
}
private CancellationTokenSource _tokenSource = new();
private readonly ApplicationPartManager _applicationPartManager;
private readonly ILogger<WebApiOptions> _logger;
public bool HasChanged { get; private set; }
public IChangeToken GetChangeToken() => new CancellationChangeToken(_tokenSource.Token);
public void InterfacesAsControllers(List<Type> interfaceTypes)
{
var assembly = DynamicControllerGenerator.GeneratController(interfaceTypes);
var partFactory = ApplicationPartFactory.GetApplicationPartFactory(assembly);
foreach (var applicationPart in partFactory.GetApplicationParts(assembly))
{
_applicationPartManager.ApplicationParts.Add(applicationPart);
}
HasChanged = true;
var source = _tokenSource;
_tokenSource = new CancellationTokenSource();
source.Cancel();
if (_logger is null)
{
return;
}
foreach (var type in assembly.GetTypes())
{
var intfc = type.GetInterfaces().Where(x => interfaceTypes.Contains(x)).FirstOrDefault();
if (intfc is not null)
{
_logger.LogInformation($" DynamicController -> {type.Name}: {intfc.FullName}");
}
}
}
}
}
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/zijian666/WebApiExtensions.git
git@gitee.com:zijian666/WebApiExtensions.git
zijian666
WebApiExtensions
WebApi脚手架
master

搜索帮助