Doing it once during compilation and then working off of that is great. Reflection is another example, where much of the time you don’t want to go through every single type in every assembly at runtime, but just want to figure out which things are connected. In addition, you can also do it to precompute stuff that already is doable at runtime but is “needlessly dynamic”, as in the examples above, where the alternative is to dynamically grab things that could have been burned in at compile-time. Microsoft would probably never adopt something like PostSharp into the framework this, they might use.
Separation studio practice file code#
There are already ways to generate code, but to have a specified place in the compilation pipeline where it happens, and to have the compiler and IDE know all about it gives it much better robustness, not to mention being able to more easily distribute code generators as sidecar packages to, for example, serialization libraries. I agree with the basic gist since I would love to have macros in C# tomorrow in their absence, it’s good to have the ability to do some of the same things with code generation. It, like some “design patterns”, can easily be the echo of a missing feature.
Separation studio practice file generator#
In our client code, we pass the inputs to the generator as below: We embed our input in assembly attributes and then, in the generator code, we fish them out of the assembly to Mustache Generator Usageįor the Mustage Generator, we use a different way to pass input arguments compared to the CSV Generator above.
This is what gets compiled into your project, so that you can reference it from the code. Given such input, the generator creates a CSV namespace that you can import in your code with: The generation of classes representing the shape of the CSV file happens at compile time, while the creation of the objects for each row of the file happens at run time according to the policy specified by CsvLoadType and CacheObjects.īTW: the 11Age column name came about as a way to test that the C# generation is correct in case of columns starting with a number. It can be a little confusing to keep straight when exactly every phase runs.
CacheObjects is a bool indicating if the objects need to be cached after creation. CsvLoadType can take the value of Startup or OnDemand: the former instruct the code to load the objects representing the CSV file when the program starts the latter loads them at first usage. There are two additional arguments that get passed as part of the input in the project file AdditionalFiles tag: CsvLoadType and CacheObjects. Where the People.csv file looks like so: Name, address, 11Age In the samples project this is achieved by the following instruction in the project file: You use a generator in your project by either referencing a generator project or by referencing the generator assembly directly. In this post we explore two different ways to provide it. The inputs to a generator must be available at compile time, because that’s when generators run. In fact, its output becomes part of the project. This ‘function’ runs before the code for the main project is compiled. Conceptually, a generator is a function that takes some input (more on that later) and generates C# code as output. It is important to have a good mental picture of how source generators operate. The second one creates string constants based on Mustache specifications. The first generator gives you strongly typed access to CSV data. This post describes two new generators that we added to the samples project in the Roslyn SDK github repo. Phillip introduced C# Source Generators here.