Hi Jon, Am Mittwoch, 9. März 2016 13:59:32 UTC+1 schrieb Jon Skeet: > > Indeed there isn't. It's not clear to me at what point messages would get > registered - after all, a new assembly with extra messages could be loaded > at any point. >
I'm not completely up to date on module initialization in CLR. Is there still no native language support for it? I only know this 7 year old workaround, but this is done after building: http://einaregilsson.com/module-initializers-in-csharp/ Also I just found this post about a nuget package: http://geertvanhorrik.com/2013/06/28/assembly-constructors-and-initializers-using-c/ Also not a good solution for including it in a library... Would be a bit sad if Microsoft still offers no support to access this CLR feature. I understand that static constructors are only called when the type is referenced for the first time. Another possible (also if not as performant) option I successfully tried was reflection. https://github.com/Falco20019/protobuf/commit/74e5a82593787610f2207423bf3a8a8449a78813 By introducing a common interface, you can look them up in the AppDomain. Here is the test class I used to generate a TypeRegistry from all currently loaded assemblies. This is not cached but calculated on request since new assemblies can be introduced as you said. public static TypeRegistry GetTypeRegistry() { List<FileDescriptor> descriptors = new List<FileDescriptor>(); AppDomain.CurrentDomain.GetAssemblies() .SelectMany(s => s.GetTypes()) .Where(p => typeof(IReflection).IsAssignableFrom(p) && !p. IsInterface) .ToList() .ForEach(type => { var pi = type.GetProperty("Descriptor", BindingFlags.Public | BindingFlags.Static); var value = pi.GetValue(null); descriptors.Add((FileDescriptor)value); }); return TypeRegistry.FromFiles(descriptors); } Calling GetValue on the property initializes the type and returns the descriptor. If you only want to call your static constructor for all classes, you could use System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(type.TypeHandle); This is better than invoking TypeInitializer which leads to the constructor being called multiple times (as you also wrote on StackOverflow 6 years ago :) ). I also thought about just using IMessage for the lookup and use Descriptor to initialize the TypeRegistry with FromMessages, but this would finds a lot more types which would make the reflection part slower. -- 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.
