实现动态Controller插件化
using Hoa;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Emit;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
namespace Proxy
{
public class ProxyClass
{
/// <summary>
/// 万能接口
/// </summary>
/// <param name="code">传入你要实现的代码</param>
/// <returns>动态生成一个程序集</returns>
public static Assembly GenerateProxyTree(string code)
{
Assembly assembly = null;
SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(code);
string assemblyName = "Hoa.Dynamic.WebApi";
//var ass = AppGlobal.ApplicationAssembiles;
var ass = new List<Assembly>();
ass.Add(typeof(object).Assembly);
//ass.Add(typeof(Attribute).Assembly);
ass.Add(Assembly.Load("System.Runtime"));
ass.AddRange(AppGlobal.ApplicationAssembiles);
var references = ass.Select(x => MetadataReference.CreateFromFile(x.Location));
CSharpCompilation compilation = CSharpCompilation.Create(assemblyName, new[] { syntaxTree }, references, new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
using (var ms = new MemoryStream())
{
EmitResult result = compilation.Emit(ms);
if (result.Success)
{
ms.Seek(0, SeekOrigin.Begin);
assembly = Assembly.Load(ms.ToArray());
}
}
return assembly;
}
}
}
using Hoa.Dependencies;
using Hoa.ServiceController.Attributes;
using Microsoft.AspNetCore.Mvc;
using Proxy;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace Hoa.Web.Host
{
public static class AssClass
{
private static readonly Func<Assembly, IEnumerable<Type>> queryControllerTypesExp =
ass => ass.GetTypes().Where(type => IsControllerType(type));
private static bool IsControllerType(Type type)
{
if ((!type.IsInterface && !type.IsAbstract && !type.IsGenericType && type.IsPublic)
&& ((type.IsDefined(typeof(HoaServiceControllerAttribute))
&& !type.IsDefined(typeof(HoaNonServiceWebApiAttribute))
&& (
!type.IsDefined(typeof(ApiExplorerSettingsAttribute))
|| (type.IsDefined(typeof(ApiExplorerSettingsAttribute)) && type.GetCustomAttribute<ApiExplorerSettingsAttribute>().IgnoreApi != true)
)
)
)) return true;
return false;
}
public static Assembly GetAss()
{
var stringBuilder = new StringBuilder();
stringBuilder.AppendLine("namespace Hoa.Dynamic.WebApi");
stringBuilder.AppendLine("{");
var controllerTypes = AppGlobal.ApplicationAssembiles.SelectMany(queryControllerTypesExp);
foreach (var serviceType in controllerTypes)
{
var serviceTypeInterface = serviceType.GetInterface($"I{serviceType.Name}", true);
stringBuilder.AppendLine("[Hoa.ServiceController.Attributes.HoaServiceController]");
stringBuilder.AppendLine($"public class HoaDynamic{serviceType.Name}: {typeof(IAppServiceDependency).FullName}");
stringBuilder.AppendLine("{");
stringBuilder.AppendLine($"private readonly {serviceTypeInterface.FullName} _service;");
stringBuilder.AppendLine($"public HoaDynamic{serviceType.Name}({serviceTypeInterface.FullName} service)");
stringBuilder.AppendLine("{");
stringBuilder.AppendLine("_service = service;");
stringBuilder.AppendLine("}");
var methods = serviceType.GetMethods(BindingFlags.Instance | BindingFlags.Public).Where(u => u.DeclaringType == serviceType);
foreach (var method in methods)
{
var parameterDefines = string.Join(",", method.GetParameters().Select(u => $"{u.ParameterType.FullName} {u.Name}").ToArray());
var parameterDeliver = string.Join(",", method.GetParameters().Select(u => $"{u.Name}").ToArray());
stringBuilder.AppendLine($"public {(method.ReturnType == typeof(void) ? "void" : method.ReturnType.FullName)} {method.Name} ({parameterDefines})");
stringBuilder.AppendLine("{");
stringBuilder.AppendLine($"{(method.ReturnType == typeof(void) ? "" : "return")} _service.{method.Name}({parameterDeliver});");
stringBuilder.AppendLine("}");
}
stringBuilder.AppendLine("}");
}
stringBuilder.AppendLine("}");
string code = stringBuilder.ToString();
var ass = ProxyClass.GenerateProxyTree(code);
return ass;
}
}
}
public void ConfigureServices(IServiceCollection services)
{
services.AddHoaServicesBefore(Configuration);
services.AddControllers()
.AddApplicationPart(AssClass.GetAss())
.AddNewtonsoftJson();
services.AddHoaServices();
}
如果您觉得本文对你有用,不妨帮忙点个赞,或者在评论里给我一句赞美,小小成就都是今后继续为大家编写优质文章的动力,百小僧拜谢!
欢迎您持续关注我的博客:)
版权所有,欢迎保留原文链接进行转载:)