zoukankan      html  css  js  c++  java
  • 实现动态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();
            }
    
  • 相关阅读:
    Java实现 蓝桥杯VIP 算法提高 P0404
    Java实现 蓝桥杯VIP 算法提高 P0404
    Java实现 蓝桥杯VIP 算法提高 P0404
    Java实现 蓝桥杯VIP 算法提高 P0404
    Java实现 蓝桥杯VIP 算法提高 P0404
    Java实现 蓝桥杯VIP 算法训练 排列问题
    Java实现 蓝桥杯VIP 算法训练 排列问题
    Java实现 蓝桥杯VIP 算法训练 排列问题
    Java实现 蓝桥杯VIP 算法训练 排列问题
    关于模态/非模态对话框不响应菜单的UPDATE_COMMAND_UI消息(对对WM_INITMENUPOPUP消息的处理)
  • 原文地址:https://www.cnblogs.com/baiqian/p/12739464.html
Copyright © 2011-2022 走看看