Make PCL-friendly C# classes with protobuf-net generator - c#

I would like to use Protocol Buffers in a Xamarin app, so I need to use a PCL project to house my non-platform-specific code.
I used the protobuf-net protogen to convert a .proto file into a .cs file, but it was incompatible with PCL projects. Making it compatible was as easy as removing every global::System.Serializable attribute from the file, but I'd like to know if there is a way to make the protogen not put those attributes in the generated file.
This would be very helpful if I were to a) find a way to automatically build .proto classes, b) change some of the very many message types on a regular basis, or c) hand over the project to someone who doesn't understand the problem.

Yes, the protogen tool has options to emit that. Try adding -p:lightFramework to enable this. -p:help should show the other options provided by the chosen language plugin.

Related

Best approach to reading and writing values from DLL at runtime

I’m creating a class library DLL which will be used by others. I have no knowledge of what that project will be, what the project name will be and etc. When it’s all said and done, all I will be doing is handing them the DLL for any project to reference.
The problem now is that I need a way for my DLL to be able to read and load key/values from the project at runtime. The project will pass the key/values to my DLL and said DLL will do the reading and writing of these key/values. I’ve found out that there are multiple ways to do that:
1) User settings from Settings/Appconfig
2) Create a new XML file to read and write from
However both ways are not automated. Correct me if I’m wrong:
For 1) The project side will have to manually create a Settings file with the key/values my DLL needs.
For 2) The project side will have to manually create an XML file with the key/values my DLL needs. Plus my DLL will need to know where that XML is being saved by the project referencing it (so that I can read and write from it from the DLL)
This is where I need help. Is there a way I can achieve reading and writing values from my DLL at runtime without the project having to do any manual work? And if not, what would be the best approach to go about this? Hand over a Settings file to the people who will be referencing my DLL?
Thanks!
Well, the client (the project using your dll) will have to do something in order to use you dll, right.
Your choice is to either define a way of configuration or to change your interface, so that the caller can provide the key-value pairs directly. You can still use app-settings from the consuming application's configuration-file. Your DLL can access them by using System.Configuration.ConfigurationManagerwithout having to know anything about where the application is running.
The only thing the other project would have to do is to provide the settings you need in the config.
But maybe you could elaborate a little more on what you are actually trying to do, "reading values" is not very specific.

Including a C++ header file in a c# file

I was converting a Managed c++ project to a C# one. The C++ project includes a constants C++ header file which is an external dependency present outside of the project.
In the newly created C# file, is there a way to include this C++ header file? I dont want to redefine these constants in a C# file as changes by clients will take place on the C++ header file.
It's not possible to include it.
You have 2 options really
duplicate it for the managed layer, and maintain it in synch with the C++ header.
read and parse it at runtime, and use reflection in the C# parts that require those symbols.
As noted by others, you can automate the first one.
If you have a huge amount of header files, you can take a look at SWIG: http://www.swig.org/
This will generate C# files from C/C++ header files.
For more info see also: http://www.swig.org/Doc2.0/SWIGDocumentation.html#CSharp
The results are quite impressive! But the naming is more C++ like, than C# style... but this was expected...
Unfortunately no, that isn't possible as the C# compiler doesn't understand what to do with .h files. Even it if did, it still illegal to have un-scoped variables declarations (constant or otherwise) in .NET.
You'll have to convert the file either by hand, or as mentioned in the comment by Joachim Pileborg, build a utility to auto-convert it to C# code for you.

compiling proto files at runtime

I'm working a generic protobuf decoder that works as follows:
The user can specify the .proto file at runtime and specify the data file and the program would display the data in the file based on the .proto definition.
To do the above, the most obvious things seems like I would need to interpret the .proto file (or compile it) and then decode the protobuf message using it. Any ideas on how I can proceed on this? Is there a library out there that would help me with this.
As always, any feedback is much appreciated.
Thanks!
I keep meaning to write my own parser, but for now I just use "protoc" to parse the .proto to a protobuf binary. I then deserialize that using my own protobuf library, giving me a populated object model to work with.
I don't know how far along you are, but you might also be interested in some of the runtime support in protobuf-net v2, which allows on-the-fly mapping of protobuf data to types. Alternatively there's also a fairly re-usable reader implementation that might suit your needs.
If you could work from XML, I include a tool in protobuf-net, "protogen", which does code-gen; but pass in a -t:xml and it should transform a .proto into XML for you.
Iirc, "protoc" outputs a protobuf using "descriptor.proto" from the google package.

XSD.exe and "Circular Group references"

I am attempting to build some classes so that I can deserialise an XML file created by a third party application. Luckily the developer of the 3rd party application included a schema file with their code so that the XML file can be understood.
When I use the XSD.exe tool from Visual Studio the process fails reporting the following error
"Group 'SegGroupOrSegmentGrouping' from targetNamespace='' has invalid definition: Circular group reference."
Any help in how I can generate the class files in light of this error would be appreciated.
A copy of the schema file can be found here : schema file
Try using svcutil; it can handle the circular references.
In the following example, eExact-Schema.xsd is an XSD that xsd.exe cannot handle.
Example:
C:\SRC\Exact>svcutil eExact-Schema.xsd /language:C# /dataContractOnly /importxmltypes /out:exact.cs
This is always a good place to start; you can now use this class and alter to suit your style/needs, add comments, etc, and it will save you a lot of time/searching over doing it all from scratch.
I had this same problem recently,
I was given a Schema from a third party company who were returning an xml structure from a webservice. I then wanted to deserialise the response and store the information into a database with NHibernate.
No problem I thought I'll just use xsd.exe and I'll have my classes. Unfortunately this was not to be. Xsd.exe failed with exactly the same error you are getting. This is because it is unable to resolve circular references.
I spent a good few days looking at alternatives until in the end I wrote my own class structure to the schema and was able to deserialise perfectly. The answer here is to write your own C# classes and decorate them with the appropriate attributes.
Save yourself some time and heartache and don't continue to try and generate the classes you need automatically in the end although time consuming the classes you write won't make the compromises that most tools (which don't work perfectly) will make you make.
Took me about 3 days to write the class structure (it was large) but I ended up with a quality solution.
One thing is certain you will not be able to use xsd.exe and most other tools I tried after googling this either did not work properly or were buggy.
After trying several third party tools, I found that Liquid Technologies has a very robust generator called Liquid XML Data Binder 2012. It was able to handle the circular group reference problem I faced. It can generate code for just about any version of .net from 2.0 on. The classes it generates do depend on a redistributable dll that they provide. I'm using the trial version and I wouldn't be surprised if a purchase of the full version will be necessary before I go to release. However, having saved me probably a hundred hours or more of error prone hand coding, I can't complain.
The easiest method for me is to create the XSD file from the actual XML file with XSD.EXE. Then create a class from the new XSD file. You may be required to modify the class periodically if nodes or types are introduced that did not exist in the original XML but you will save yourself HOURS of coding time!!!!

C# Code Generation

I am looking at creating a small class generator for a project. I have been reading about CodeDOM so it the semantics of creating the classes does not appear to be an issue, but am unsure oh how to best integrate the generation into the development and deployment process.
How should I trigger the creation of the classes? I have read it should be part of the build process, how should I do this?
Where should the classes be created? I read that the files should not be edited by hand, and never checked into source control. Should I even worry about this and just generate the classes into the same directory as the generator engine?
Take a look at T4 templates (it's built in to VS2008). It allows you to create "template" classes that generate code for you. Oleg Sych is an invaluable resource for this.
Link for Oleg's tutorial on code generation.
The answers to your question depend partly on the purpose of your generated classes.
If the classes are generated as a part of the development, they should be generated as text files and checked into your SCM like any other class.
If your classes are generated dynamically at runtime as a part of the operation of your system, I wouldn't use the CodeDOM at all. I'd use Reflection.
I know of the presence of T4 templates (and know many people use them), but I have not used them myself. Aside from those, you have two main options:
Use a SingleFileGenerator to transform the source right inside the project. Whenever you save the document that you edit, it will automatically regenerate the code file. If you use source control, the generated file will be checked in as part of the project. There are a few limitations with this:
You can only generate one output for each input.
Since you can't control the order in which files are generated, and the files are not generated at build time, your output can only effectively be derived from a single input file.
The single file generator must be installed on the developer's machine if they plan to edit the input file. Since the generated code is in source control, if they don't edit the input then they won't need to regenerate the output.
Since the output is generated only when the input is saved, the output shouldn't depend on any state other than the exact contents of the input file (even the system clock).
Generate code as part of the build. For this, you write an MSBuild targets file. For this, you have full control of input(s) and output(s) so dependencies can be handled. System state can be treated as an input dependency when necessary, but be remember that every build that requires code generation takes longer than a build which uses a previouly generated result. The results (generated source files) are generally placed in the obj directory and added to the list of inputs going to csc (the C# compiler). Limitations of this method:
It's more difficult to write a targets file than a SingleFileGenerator.
The build depends on generating the output, regardless of whether the user will be editing the input.
Since the generated code is not part of the project, it's a little more difficult to view the generated code for things like setting breakpoints.

Categories