This works in Java, perhaps you can adapt it to C# (?) https://github.com/os72/protobuf-dynamic
Is there DynamicMessage in the C# API? On Monday, May 16, 2016 at 10:30:18 AM UTC-7, [email protected] wrote: > > Hi, > > I wanted to generate FileDescriptor dynamically from .proto without > referencing, as in the given example we have reference Student.Interop.DTO > so that we can get the StudentDTO.Descriptor and EmployeeDTO.Descriptor, so > i wanted to avoid this reference. > > *Example :* > namespace Student.WebApi > { > using System.Web.Http; > using Framework.WebApi.Formatters; > using Google.Protobuf.Reflection; > using Repository; > using Student.Interop.DTO; > > public class WebApiApplication : System.Web.HttpApplication > { > protected void Application_Start() > { > GlobalConfiguration.Configure(WebApiConfig.Register); > var json = > GlobalConfiguration.Configuration.Formatters.JsonFormatter; > json.SerializerSettings.Converters.Add(new > AnyJsonConverter(TypeRegistry.FromMessages(StudentDTO.Descriptor, > EmployeeDTO.Descriptor))); > > } > } > } > > So to achieve this following few steps i tried : > > *Step 1* : Sample Proto i.e Student.proto which consist of message type > i.e StudentDTO and EmployeeDTO > > syntax = "proto3"; > package AnalysisConsoleApplication; > import "google/protobuf/any.proto"; > option csharp_namespace = "AnalysisConsoleApplication"; > > message StudentDTO > { google.protobuf.Any Any = 1; > string USN = 2; > string Name = 3; > string University = 4; > } > message EmployeeDTO > { > string Name = 1; > string Gender = 2; > } > > Step 2 : I generated Student.pb by using below command i.e > > .\protoc.exe --proto_path=D:\Proto Proto\Student.proto --include_imports > --descriptor_set_out=D:\AnalysisConsoleApplication\Student.pb > > Step 3 : If i reference Google.Protobuf.3.0.0-beta2 in my > SampleConsoleApplication and try to use FileDescriptor class then it will > give error as recently in updated version FileDescriptor is of Internal > sealed class. so i clone the Google.Protobuf repository which was of > Google.Protobuf.3.0.0-beta2 release time, at that time FileDescriptor class > was public sealed class. Now my SampleConsoleApplication solution will > have another project which is of Google.Protobuf. > > Note: SampleConsoleApplication zip file is been attached for detail > understanding. > > This code is from Actual generated C# file(Student.cs) from the given > proto, but now next step we will create this below descriptorData dynamically > from Student.pb > byte[] descriptorData = global::System.Convert.FromBase64String( > string.Concat( > "Cg1TdHVkZW50LnByb3RvEhpBbmFseXNpc0NvbnNvbGVBcHBsaWNhdGlvbhoZ", > "Z29vZ2xlL3Byb3RvYnVmL2FueS5wcm90byJeCgpTdHVkZW50RFRPEiEKA0Fu", > "eRgBIAEoCzIULmdvb2dsZS5wcm90b2J1Zi5BbnkSCwoDVVNOGAIgASgJEgwK", > "BE5hbWUYAyABKAkSEgoKVW5pdmVyc2l0eRgEIAEoCSIrCgtFbXBsb3llZURU", > "TxIMCgROYW1lGAEgASgJEg4KBkdlbmRlchgCIAEoCUIdqgIaQW5hbHlzaXND", > "b25zb2xlQXBwbGljYXRpb25iBnByb3RvMw==")); > descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, > new pbr::FileDescriptor[] { > global::Google.Protobuf.WellKnownTypes.AnyReflection.Descriptor, }, > new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] { > new > pbr::GeneratedCodeInfo(typeof(global::AnalysisConsoleApplication.StudentDTO), > global::AnalysisConsoleApplication.StudentDTO.Parser, new[]{ "Any", "USN", > "Name", "University" }, null, null, null), > new > pbr::GeneratedCodeInfo(typeof(global::AnalysisConsoleApplication.EmployeeDTO), > > global::AnalysisConsoleApplication.EmployeeDTO.Parser, new[]{ "Name", > "Gender" }, null, null, null) > })); > > Step 4: Now to generate descriptorData dynamically from Student.pb, i > have written the following code which gives the descriptorData in byte[] > > //get the path of Student.pb > var path = string.Format("{0}/Student.pb", Path.GetDirectoryName(new > Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath)); > //create messageParser > MessageParser<FileDescriptorSet> messageParser = new > MessageParser<FileDescriptorSet>(() => new FileDescriptorSet()); > // open and read it > CodedInputStream stream = new CodedInputStream(new FileStream(path, > FileMode.Open)); > //Parses a message from the given coded input stream. > var data = messageParser .ParseFrom(stream); > //Covert to ByteString > var descriptorData = data.File[0].ToByteString(); > > Step 5: Last step to generate filedescriptor by calling > FileDescriptor.FromGeneratedCode() > which accepts 3 parameters > Parameter 1: byte[] descriptorData -> this parameter we are able to > generate dynamically as done in step 4 i.e descriptorData.ToByteArray() > > Parameter 2: FileDescriptor[] dependencies-> this takes all the > dependencies. > Parameter 3: GeneratedCodeInfo generatedCodeInfo-> This has > GeneratedCodeInfo(Type > clrType, MessageParser parser, string[] propertyNames, string[] oneofNames, > Type[] nestedEnums, GeneratedCodeInfo[] nestedTypes) out of this > parameters i am not able to get clrtype dynamically. > > *Here is the brief example of what i am expecting:* > typeof(global::SampleConsoleApplication.StudentDTO): this gives the type > i.e clrtype of StudentDTO which is of public sealed class, which will be > generated in Student.cs by executing the Student.proto. But I am trying to > get the clrtype without generating Student.cs, so because of which > typeof(global::SampleConsoleApplication.StudentDTO) > can't be used here. > > > -- You received this message because you are subscribed to the Google Groups "Protocol Buffers" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at https://groups.google.com/group/protobuf. For more options, visit https://groups.google.com/d/optout.
