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();
            }
    
  • 相关阅读:
    15道简单算法题
    提高SQL查询效率
    算法--两道百度笔试题
    .NET牛人应该知道些什么?
    VS创建、安装、调试 windows服务(windows service)
    Build System 和Test Framework overview总结
    3.8 Templates -- Actions
    3.7 Templates -- Links
    3.6 Templates -- Binding Element Class Names(绑定元素类名)
    3.5 Templates -- Binding Element Attributes(绑定元素属性)
  • 原文地址:https://www.cnblogs.com/baiqian/p/12739464.html
Copyright © 2011-2022 走看看