Dynamic DbContext Generation - visual-studio

I need to write a web site content management system that makes use of dynamic Entity Framework DbContext generation. As an input I get a custom data types declaration (in xml) that my C# code knows how to parse. On the output, I need to obtain the code for the DbContext that would provide a facility to store the provided data type instances as DbSet's in a database.
I can see there is .tt -> .cs Generator in a form of a plugin for Visual Studio. I can surely create code that would generate an xml-based (I assume it is) .tt template from my custom declaration and then generate a .cs DbContext for this .tt. But how do I run .tt->.cs conversion manually from code?

Usually T4 templates are transformed at design time inside Visual Studio. If you want to use a T4 template at runtime, change the value of the "Custom Tool" property of the .tt's Project item to "TextTemplatingFilePreprocessor".
This will make Visual Studio create a C# class from your T4 template that can be instantiated at runtime, where you can pass parameters to it (e.g. your xml type declaration). Calling the "TransformText()" will return the actual output code of the T4 template containing the data classes.
In order to use those classes at runtime, too, you would need to compile the output code in memory.

Related

Changing default T4 template for new EDMX files

How do I force VS to choose a custom template when creating EF models?
Details:
I built a custom template for generating EF entity classes from models. The solution has many projects with their own models and it is likely more will be added over time.
In order to prevent bugs in the future, I'd like to force VS to choose my template by default when creating EF models in the future. I'd prefer this to be at the Solution level, so that the change is part of the repository.
I have the template exported as a VS Item Template that is basically a clone of the default EF 6.x DbContextGenerator with the appropriate values replaced. I'm able to run it manually by using the "Add Code Generation Item..." option on the model designer view.

How can we get the T4 template to generate code based on a .cs file that the user is editing?

I'm trying to create a T4 template that will save our developers from creating a lot of boilerplate code that's necessary in our framework. Let's say the developer creates an interface and marks it with our custom attribute. I would like it so that any interface marked with that custom attribute is enhanced by additional methods, which means my T4 template would have to generate partial classes on the fly. However, I would like it so that this automatic generation happens on the fly and seamlessly, preferably when the internal automatic compilation that's used for intellisense happens. You know how when you create a new class in Visual Studio and you switch to another source file and start using that class you didn't have to save or compile it, Intellisense was able to see the new class you created right away? I'd like the same automatic behavior with the code generated from my T4 template. Any thoughts?
You cannot do what you want to do easily, but here are some options ordered from easiest to most likely what you want (hardest).
Create code
snippets
Create a Visual Studio Item Template
Use Castle DynamicProxy to create the extra bits at run time.
Create a separate project to hold the T4 generated classes as described in my answer here
As a pre-step to your project build (modify .csproj file to do this), you can compile the source code from which you want to generated code and then reflect on that, generate the code and then add it to the project before the real compile step. This is what the MSR Orleans project does. You can read their source code here. This is really cool! :-)

Creating a data driven resource manager while keeping the VS2010 designer features

I'm quite used to consume resx designer generated classes, for a clean coding and to avoid mistakes.
However, in a specific project, I need to rely to a database table, containing all labels and their translations in several languages.
I could simply create my own class and get the translated label, however I'd also like to take advantage of VS2010 resource manager and autogenerated *.Designer.cs classes.
I didn't figure out how to do that.
The *.Designer.cs file contains the following comment:
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
So, I suppose I must use the StronglyTypedResourceBuilder (or my own version of this class).
But how to automatically build the class during the design?
And how to save/retrieve data from the DB?

Two Custom tool s for a single file?

I want to generate some code from my dbml(Linq to Sql) file,the dbml file is placed in many part of my project So I wrote a custom tool for this purpose
But the problem is that dbml already has contained MSLinqToSQLGenerator custom tool ,
So do you know any way to set two custom tools for one file, If no, Let me know your idea about that
Visual Studio will only support a single "Custom Tool" per file, but you can add a pre-compilation step to run other tools against anything you want. For instance, I have the following pre-compile step set on the "Build Events" tab of one of my projects.
"$(DevEnvDir)..\..\..\Common Files\Microsoft Shared\TextTemplating\10.0\TextTransform" "$(ProjectDir)DataContext\Northwind.proxy.tt"
There's a lot of relative pathing going on here in order to find the T4 command-line tool, but you get the idea. This particular T4 file counts on being in the same directory as the .dbml file that it reads to generate its output.
Before the project is compiled, you can run whatever external tool you want. Just make sure that after the first run, you include the tool's output in the project. After that, since the file gets changed as part of a PRE-compile step, it will always be updated in each build.
You'd get proper control on the T4 if you include the LINQ to SQL T4 generator in your template's responsibility.
If I understood properly, you want to keep the default behavior of .dbml generator, but also add your own.
This seemed a bit "old", and I haven't personally used LINQ to SQL for some time, but I did use this as-is replacement of T4 generator, that produced the equivalent of the standard .dbml generator.
https://github.com/damieng/L2ST4
Not sure if that's up to date with VS 2010 version, but you can always compare the standard .dbml generated code and this T4 output and make proper changes to achieve identical outcome.
Of course you can simply have multiple different generators, and simply run them with "Transform All Templates", but based on your question, you'd want the generator to be attached to the file specific custom tool.
You might want to check out (unless its already familiar to you) also T4 Toolbox https://github.com/olegsych/T4Toolbox that adds "T4ScriptFileGenerator" custom tool to a file. It effectively runs the T4 code when the file changes.

How to use T4 and Visual Studio to Extend a Partial Class

I wanted to use T4 to generate properties for a partial class. I'm running into a configuration problem where my .TT file is in the same project as the class file I want to extend. So if I have to include the assembly in the .TT file it get's locked. I tried to do a command line in the pre-build but the problem there is that VS always wants to recompile the .TT file with the project.
The only solution I can think of is to rename the .tt files to say .t4 and then use a pre-build command with TextTransform -out to create the .cs file in the project directory.
Can anyone think of a cleaner way to do this?
Assuming that locking is caused by your template using Reflection to read metadata of the partial class you need to extend, you could solve the locking problem if you use CodeModel. This API is provided by Visual Studio and allows you to get the metadata directly from the source file, without the need to compile the partial class or load the compiled DLL. Here is an example of a T4 code generator that uses this approach: http://www.olegsych.com/2008/07/t4-template-for-generating-sql-view-from-csharp-enumeration

Resources