T4 "Compiling transformation: An assembly with the same identity ' ' has already been imported. Try removing one of the duplicate references."? - visual-studio-2010

I've been struggling with
Compiling transformation: An assembly with the same identity 'xxxx' has already been imported. Try removing one of the duplicate references.
When using T4 to generate some code at design time - with a couple of different reusable templates saved as .ttinclude files, and shared in a number of different "parent" templates.
I toggle between this, and the alternative when I remove one of the references (in my own ttinclude file) which is :
Compiling transformation: The type or namespace name 'yyy' could not be found (are you missing a using directive or an assembly reference?)
Going round in circles, any ideas?

Well, found a dirty workaround.
Would love a better solution / approach, if someone has some advice?
Posting my process as might be helpful to someone else.
Used the template directive to put my templates and include
templates into debug mode e.g.
<## template language="C#" debug="true" hostspecific="true"#>
Popped open %TEMP% to look at the generated file(s) (most recently
modified) just after getting the compiling transformation error.
Searched for the missing / doubled up assembly / class(es) used.
Found which "included" templates both had same reference e.g.
<## include file="MyHelperTemplate.ttinclude" #>
and :
<## include file="EF.Utility.CS.ttinclude" #>
Opened the include folder for the non custom include that was
causing the conflict with my own
..\Common7\IDE\Extensions\Microsoft\Entity Framework Tools\Templates\Includes
Opened this file up, removed its troublesome import
<## import namespace="EnvDTE" #>
Saved it with a new name in same folder and updated references to point to this new version e.g.
<## include file="EF.Utility.CS.Custom.ttinclude" #>
Put required imports into the "parent" templates, and removed from
the "include" template. In my case this was:
<## import namespace="EnvDTE" #>
Now it runs fine, no problems at all, no duplicated imports, and all required assemblies referenced correctly.
Am sure there is a much more sophisticated way of dealing with T4 code reuse which negates this problem entirely. I initially tried importing my own custom assembly, with helpers for the templates, but had what seems like a classic problem with locked dlls when I then tried to build my custom class library.
Seems T4 Toolbox has a solution to this with the VolatileAssembly Custom Directive, and is popular, but looks a bit overkill for my fairly simple needs. Maybe when I have more time.

Related

Deleted files gives CS0246 compiler error in VS2022

I've added 3 default Blazor projects to my solution.
Blazor WebAssembly1
Blazor WebAsssembly2
Blazor Server
The first WebAssembly project is converted to a razor library in order to share code between server and webassembly projects. I also deleted the default pages like FetchData.razor and such.
On compilation I still get compile error on this (the app runs fine though), and I can't seem to resolve them. I've search through the entire solution but can't find any of the files that results in the compile errors.
How to locate the reason for the errors and remove the references? The files are deleted from the project.
Example of compiler error:
CS0246 The type or namepace 'WeatherForecastService' could not be found (are you missing a using directive or an assembly reference?)
The errors in FetchData indicate a problem with the using statements.
Try to check if you have global using, try to remove and declare explicit in the razor page.
Check your CSPROJ and verify the project type, in the RCL the type must be:
<Project Sdk="Microsoft.NET.Sdk.Razor">
In the RCL you haven't a Program/App structure, you have only components and wwwroot elements.
My RCL is composed as follow:
I have also a _Imports.razor with:
#using Microsoft.AspNetCore.Components.Web
...
The issue resolved itself when I restarted Visual Studio.
Sorry for the wild goose chase

How to prepare the T4's environment to use SQLite?

I am having a hard time to properly set up the environment for T4 to recognize the Sqlite provider. Steps I have taken:
Add assemblies and imports to in .tt
<## assembly name="\System.Data.SQLite.dll" #>
<## import namespace="System.Data.SQLite" #>
At the beginning of tt, add SQLite as one of the providers.
// add sqlite
try
{
var dataSet = ConfigurationManager.GetSection("system.data") as System.Data.DataSet;
dataSet.Tables[0].Rows.Add("SQLite Data Provider"
, ".Net Framework Data Provider for SQLite"
, "System.Data.SQLite"
, "System.Data.SQLite.SQLiteFactory, System.Data.SQLite");
}
catch (System.Data.ConstraintException) { }
I verified in SQLite is one of the providers in DbProviderFactories.
This didn't get SQLite to load by T4. Under a normal application, a SQLite entry would be added to the App.config section. SQLite somehow preloads a native dll. I suspect the preloading is the problem.
After some digging, I resolved the problem by installing System.Data.Sqlite. The installer puts the library in the GAC. The additional code above is not necessary. I was trying to avoid the GAC, but didn't find another way out.

Executing T4 template: Host is null while hostspecific="True"

I am trying to write a console program that takes the file name of a T4 template as a parameter, and then processes the template. This because I want users to be able to update the template without having to recompile the program.
The simplest solution I found was to create a second template within Visual Studio that precompiles to a C# class, which in turn executes my external template "Template.tt":
<## template language="C#" hostspecific="True" #>
<## import namespace="System.IO" #>
<## import namespace="Microsoft.VisualStudio.TextTemplating" #>
<#
string template = File.ReadAllText(Host.ResolvePath("Template.tt"));
Engine engine = new Engine();
string output = engine.ProcessTemplate(template, Host);
Write(output);
#>
Within the Program.cs of my console program, I then execute this "calling" template:
string templateText = new Caller().TransformText();
Problem is that when I run this (F5), it throws a NullReferenceException on the first line in my caller template, because Host is null.
However, I thought that setting hostspecific to True would give me a Host.
What do I need to do to get a Host? Don't really want to roll my own.
Alternatively, is there a better way to execute an external T4 template?
According to the MSDN documentation the hostspecific attribute only provides access to the Host-Property inside the t4 template. It does not guarantee the presence of a host. For design-time templates (that are transformed in visual studio) Visual Studio and it's T4 engine provides this host. Unfortunately the Microsoft.VisualStudio.TextTemplating.dll is not a redistributable assembly. So you won't have that host in a run-time scenario.
As you stated, you would need to write a complete T4 engine and host yourself...
If your users need to write/alter the t4 templates, they have knowledge about programming and writing text templating. Could you think of a way to make them use visual studio in any way?
Alternatively (if the changes those user make are small) you could try to use a precompiled template that works on some other input (xml-file, ini-file, command-line-parameters, ...).
Sorry for not having better news...
The actual custom (command line app based) T4 host is not too difficult to implement, I don't recall off my head where I got the code but here are the links of our T4 modular console-app runner:
https://github.com/abstractiondev/absbuilder
The actual command line host is here:
https://github.com/abstractiondev/absbuilder/blob/master/AbstractionBuilder/CustomCmdLineHost.cs
For referencing the T4 parts, we've ran the tooling with Mono runtime / MonoDevelop environments in Linux, now based on the tests (thats 1-2 years ago), I recall that MonoDevelop's T4 was completely compatible and available as source code with some very sensible licensing (MIT or Apache 2.0 if I recall properly).

Combres, compress and combine .js and .css files

I'm trying to add the following to my ASP.Net solution. I installed it using the nuget package "Install-Package Combres.Mvc"
so far I'm not having the best luck with it as I keep getting the following error
'System.Web.Mvc.HtmlHelper' does not contain a definition for 'Combres' and no extension method 'Combres' accepting a first argument of type 'System.Web.Mvc.HtmlHelper' could be found (are you missing a using directive or an assembly reference?)
I also followed the advice of this link... and got same error:/
I'd like to make use of some compression & combination tool/framework so I'm hoping someone has any experience with this
I scrapped the whole combress/casette route after a few failed attempts. I read up a bit and saw that Asp.Net MVC 4 supports bundles/combining & compressing natievly. Which worked quite well for me.
Do you have
<%# Import Namespace="Combres" %>
On the top of the page to include the Combres namespace?
For more information (and the Razor syntax) you can also look at: http://combres.codeplex.com/wikipage?title=5-Minute%20Quick%20Start&referringTitle=Home

Oracle, Subsonic 3 and TableSpaceName

When I go to run the t4 templates, the result comes out "Compiling transformation: The name 'TableSpaceName' does not exist in the current context" -- any ideas on this? I thought it might be a namespace/reference issue, but it doesn't seem to be part of the ODP.
This is one of those "it has to be something stupid" ... why? I've got subsonic 2 to work with oracle on the same box, using the same server, same connection string so it has to be something I'm overlooking or not expecting.
I have downloaded the oracle template provider example and I've hit github for the latest and greatest, trying various combinations of both with the results being the same.
In your T4 template, check if you have imported the assembly that includes the missing 'TableSpaceName':
<## assembly name="[ABSOLUTE-PATH-TO-ASSEMBLY]\[ASSEMLBYNAME]" #>

Resources