/// <summary> /// 生成服务代理。 /// </summary> /// <param name="interfacTypes">需要被代理的接口类型。</param> /// <returns>服务代理实现。</returns> public IEnumerable <Type> GenerateProxys(IEnumerable <Type> interfacTypes) { #if NET var assemblys = AppDomain.CurrentDomain.GetAssemblies(); #else var assemblys = DependencyContext.Default.RuntimeLibraries.SelectMany(i => i.GetDefaultAssemblyNames(DependencyContext.Default).Select(z => Assembly.Load(new AssemblyName(z.Name)))); #endif assemblys = assemblys.Where(i => i.IsDynamic == false).ToArray(); var trees = interfacTypes.Select(GenerateProxyTree).ToList(); var stream = CompilationUtilitys.CompileClientProxy(trees, assemblys .Select(a => MetadataReference.CreateFromFile(a.Location)) .Concat(new[] { MetadataReference.CreateFromFile(typeof(Task).GetTypeInfo().Assembly.Location) }), _logger); using (stream) { #if NET var assembly = Assembly.Load(stream.ToArray()); #else var assembly = AssemblyLoadContext.Default.LoadFromStream(stream); #endif return(assembly.GetExportedTypes()); } }
/// <summary> /// 生成服务代理。 /// </summary> /// <param name="interfacTypes">需要被代理的接口类型。</param> /// <param name="namespaces"></param> /// <param name="serviceCommandProvider"></param> /// <returns>服务代理实现。</returns> public IEnumerable<Type> GenerateProxys(IEnumerable<Type> interfacTypes, IEnumerable<string> namespaces) { var assemblys = DependencyContext.Default.RuntimeLibraries.SelectMany(i => i.GetDefaultAssemblyNames(DependencyContext.Default).Select(z => Assembly.Load(new AssemblyName(z.Name)))); assemblys = assemblys.Where(i => i.IsDynamic == false).ToArray(); var types = assemblys.Select(p => p.GetType()); types = interfacTypes.Except(types); foreach (var t in types) { assemblys = assemblys.Append(t.Assembly); } var trees = interfacTypes.Select(p=>GenerateProxyTree(p,namespaces)).ToList(); var stream = CompilationUtilitys.CompileClientProxy(trees, assemblys .Select(a => MetadataReference.CreateFromFile(a.Location)) .Concat(new[] { MetadataReference.CreateFromFile(typeof(Task).GetTypeInfo().Assembly.Location) }), _logger); using (stream) { var assembly = AssemblyLoadContext.Default.LoadFromStream(stream); return assembly.GetExportedTypes(); } }
private static void GenerateAssembly() { using (var stream = CompilationUtilitys.CompileClientProxy(GetTrees(), AssemblyFiles.Select(file => MetadataReference.CreateFromFile(file)), Logger)) { var fileName = Path.Combine(OutputDirectory, "Rabbit.Rpc.ClientProxys.dll"); File.WriteAllBytes(fileName, stream.ToArray()); Console.WriteLine($"Generate successful path:{ fileName}"); } }
/// <summary> /// 生成服务代理。 /// </summary> /// <param name="interfacTypes">需要被代理的接口类型。</param> /// <returns>服务代理实现。</returns> public IEnumerable <Type> GenerateProxys(IEnumerable <Type> interfacTypes) { var trees = interfacTypes.Select(GenerateProxyTree).ToList(); var bytes = CompilationUtilitys.CompileClientProxy(trees, AppDomain.CurrentDomain.GetAssemblies() .Select(a => MetadataReference.CreateFromFile(a.Location)) .Concat(new[] { MetadataReference.CreateFromFile(typeof(Task).Assembly.Location) })); var assembly = Assembly.Load(bytes); return(assembly.GetExportedTypes()); }
private static void Main() { var assemblyFiles = Directory.GetFiles(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "assemblies"), "*.dll").ToArray(); var assemblies = assemblyFiles.Select(i => Assembly.Load(File.ReadAllBytes(i))).ToArray(); IServiceProxyGenerater serviceProxyGenerater = new ServiceProxyGenerater(new DefaultServiceIdGenerator(new NullLogger <DefaultServiceIdGenerator>())); Console.WriteLine("成功加载了以下程序集"); foreach (var name in assemblies.Select(i => i.GetName().Name)) { Console.WriteLine(name); } var services = assemblies .SelectMany(assembly => assembly.GetExportedTypes()) .Where(i => i.IsInterface && i.GetCustomAttribute <RpcServiceAttribute>() != null); while (true) { Console.WriteLine("1.生成客户端代理程序集"); Console.WriteLine("2.生成客户端代理代码"); var command = Console.ReadLine(); Func <IEnumerable <SyntaxTree> > getTrees = () => { var trees = new List <SyntaxTree>(); foreach (var service in services) { trees.Add(serviceProxyGenerater.GenerateProxyTree(service)); } return(trees); }; var outputDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "outputs"); if (!Directory.Exists(outputDirectory)) { Directory.CreateDirectory(outputDirectory); } switch (command) { case "1": var bytes = CompilationUtilitys.CompileClientProxy(getTrees(), assemblyFiles.Select(file => MetadataReference.CreateFromFile(file))); { var fileName = Path.Combine(outputDirectory, "Rabbit.Rpc.ClientProxys.dll"); File.WriteAllBytes(fileName, bytes); Console.WriteLine($"生成成功,路径:{fileName}"); } break; case "2": foreach (var syntaxTree in getTrees()) { var className = ((ClassDeclarationSyntax)((CompilationUnitSyntax)syntaxTree.GetRoot()).Members[0]).Identifier.Value; var code = syntaxTree.ToString(); var fileName = Path.Combine(outputDirectory, $"{className}.cs"); File.WriteAllText(fileName, code, Encoding.UTF8); Console.WriteLine($"生成成功,路径:{fileName}"); } break; default: Console.WriteLine("无效的输入!"); continue; } } }