Using .NET Core assemblies in T4 templates
Asked Answered
E

1

4

We're currently migrating a project from .NET Framework to .NET Core 3.1 and we have a problem getting some of our T4 templates to work. These templates import one or more assemblies from our solution in order to generate code using reflection. The assemblies are .NET Core 3.1 libraries. The issue seems to be that the T4 engine in Visual Studio 2019 is running on Framework and is unable to load the Core assemblies properly.

When running the templates, I'm getting a ReflectionTypeLoadException. After inspection of the exception, it becomes clear that the T4 engine can't find System.Runtime. There is some workaround for that (here), but when I apply that, that just moves the problem to the next dependency, which is a NuGet package. So the workaround doesn't work.

Is there any way to make T4 templates work with .NET Core 3.1 assemblies? Or is there any similar alternative to T4 templates that works with .NET Core 3.1?

Eternity answered 10/2, 2020 at 15:48 Comment(7)
There exists an open source (re)-implementation of T4 that does run on .NET Core. It's not very active, though, and support for Core 3 apparently requires some fiddling, as in, getting preview packages straight from the source.Drawback
Maybe you can rewrite the templates and instead of relying on reflection to extract information from compiled assemblies, get information from code files? Just to get what I'm talking about, take a look at this example.Hornet
@JeroenMostert I saw that project, but I just couldn't get the preview to work, nor could I get that environment variable to work. Plus, I'm on .NET Core 3.1 and not 3.0.Eternity
@RezaAghaei That's an interesting suggestion, but I don't think that would work. We rely on interface/class inheritance in our templates.Eternity
@Eternity I think it will be an approach, but you need to change all your t4 templates to relay on CodeClass, CodeProperty, CodeType, CodeInterface , .... It would be an expensive change though.Hornet
You could try using Mono.TextTemplating to generate your templates? Its more of a Development tool than a user interface one but the templates generatePainting
@Painting That was already suggested by Jeroen, but it doesn't support .NET Core 3.1, unfortunately.Eternity
C
7

I had this issue and couldn't find any good solutions. So I developed an alternative T4 tool that uses a hybrid of Visual Studio's .NET Framework T4 capabilities for preprocessing and a .NET Core executable to execute the template code. It is available from GitHub. It works well for my project and hopefully it can help some others too.

Cissie answered 20/3, 2020 at 16:41 Comment(5)
Unfortunately does not support "include" directive and does not work for Linq2db.Udine
@Udine Both of those statements are not true. The include directive should work normally and for Linq2db you'll need to reference the correct assemblies using the assembly directive. If you run into problems, please create an issue in the GitHub project.Cissie
This is the best Visual Studio extension that should not be necessarry, but sadly is.Jugular
This extension saved my life when migrating a project that heavily relied on T4, to .Net Core 6.Disorient
When using this extension, if you need the T4 template to have access to internal types/members of your assemblies, add [assembly: InternalsVisibleTo("GeneratedTemplate.dll")] to the AssemblyInfo.cs file of the assembly containing the internal types/members.Reprisal

© 2022 - 2024 — McMap. All rights reserved.