Skip to content

Instantly share code, notes, and snippets.

@shirhatti
Created June 27, 2019 01:33
Show Gist options
  • Save shirhatti/33471e7bbb86205c241e6420dc4a3582 to your computer and use it in GitHub Desktop.
Save shirhatti/33471e7bbb86205c241e6420dc4a3582 to your computer and use it in GitHub Desktop.
Dynamic Proxy for gRPC
using Google.Protobuf;
using Google.Protobuf.Reflection;
using Grpc.Core;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Loader;
namespace DynamicProxy
{
class Program
{
static void Main(string[] args)
{
var trees = new[]
{
CSharpSyntaxTree.ParseText(File.ReadAllText(@"D:\grpc-standup\Standup\obj\Debug\netcoreapp3.0\Adder.cs")),
CSharpSyntaxTree.ParseText(File.ReadAllText(@"D:\grpc-standup\Standup\obj\Debug\netcoreapp3.0\Greet.cs")),
CSharpSyntaxTree.ParseText(File.ReadAllText(@"D:\grpc-standup\Standup\obj\Debug\netcoreapp3.0\AdderGrpc.cs")),
CSharpSyntaxTree.ParseText(File.ReadAllText(@"D:\grpc-standup\Standup\obj\Debug\netcoreapp3.0\GreetGrpc.cs"))
};
var assemblyName = Path.GetRandomFileName();
var references = new MetadataReference[]
{
MetadataReference.CreateFromFile(typeof(object).Assembly.Location), // mscorlib.dll
MetadataReference.CreateFromFile(typeof(Enumerable).Assembly.Location), // System.Collections.dll
MetadataReference.CreateFromFile(Assembly.Load("netstandard, Version=2.0.0.0").Location),
MetadataReference.CreateFromFile(Assembly.Load("System.Runtime, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a").Location),
MetadataReference.CreateFromFile(typeof(ServiceDescriptor).Assembly.Location), // Google.Protobuf.dll
MetadataReference.CreateFromFile(typeof(BindServiceMethodAttribute).Assembly.Location), // Grpc.Core
};
var compilation = CSharpCompilation.Create(assemblyName,
syntaxTrees: trees,
references: references,
options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
using var stream = new MemoryStream();
var emitResult = compilation.Emit(stream);
if (!emitResult.Success)
{
foreach (var diagnosticMessage in emitResult.Diagnostics)
{
Console.WriteLine(diagnosticMessage);
}
throw new ApplicationException();
}
var loadContext = new AssemblyLoadContext("gRPC", true);
stream.Seek(0, SeekOrigin.Begin);
loadContext.LoadFromStream(stream);
var messageTypes = loadContext.Assemblies.SelectMany(s => s.GetTypes())
.Where(p => typeof(IMessage).IsAssignableFrom(p));
foreach (var messageType in messageTypes)
{
Console.WriteLine(messageType.FullName);
}
var binderTypes = loadContext.Assemblies.SelectMany(s => s.GetTypes())
.Where(p => (p.GetCustomAttribute(typeof(BindServiceMethodAttribute)) != null));
foreach (var binderType in binderTypes)
{
Console.WriteLine(binderType.FullName);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment