What is purpose of T4 Generator in T4toolbox - t4

I am using T4toolbox, I am confused what the generator is for. I can run the following
public class Generator1 : Generator
{
protected override void RunCore()
{
Template1 t = new Template1();
t.Output.File = "t3.txt";
t.Render();
}
}
or I can run t4 script directly like the following.
Template1 t = new Template1();
t.Output.File = "t3.txt";
t.Render();
But I can do the same using t4 script without generator as well.
So I mean can do the same thing with two approach "script --> generator --> template" and "script --> template", am I missing something?

Generator class is useful when want to encapsulate multiple templates. More here: http://www.olegsych.com/2008/09/t4-tutorial-creating-complex-code-generators/

Related

How do I define the Abp language to use during unit test execution?

I am creating unit tests for my service layer. I used the existing UserAppService_Tests test that comes with the downloaded template as a guide.
However I am seeing this exception thrown.
Abp.AbpException : No language defined!
My Test inherits from GpTestBase which in turn inherits from AbpIntegratedTestBase<GpTestModule>
GpTestModule has :
Configuration.Modules.Zero().LanguageManagement.EnableDbLocalization();
So I thought that it should be ok.
Any clues?
public override void PreInitialize()
{
Configuration.UnitOfWork.Timeout = TimeSpan.FromMinutes(30);
Configuration.UnitOfWork.IsTransactional = false;
// Disable static mapper usage since it breaks unit tests (see https://github.com/aspnetboilerplate/aspnetboilerplate/issues/2052)
Configuration.Modules.AbpAutoMapper().UseStaticMapper = false;
Configuration.BackgroundJobs.IsJobExecutionEnabled = false;
// Use database for language management
Configuration.Modules.Zero().LanguageManagement.EnableDbLocalization();
RegisterFakeService<AbpZeroDbMigrator<GpDbContext>>();
Configuration.ReplaceService<IEmailSender, NullEmailSender>(DependencyLifeStyle.Transient);
}
You should not be defining the language to use explicitly.
To have a localization context, you should login as a user.
This can happen if you don't have any languages defined in the AbpLanguages table. Example here.
In my case, it was caused by public const bool MultiTenancyEnabled = true;. Changing MultiTenancyEnabled to false, solved the problem.

What is the '.tt' extension?

I work with a bunch of something.js.tt JavaScript files using Knockout and a bunch of something-else.tt HTML files.
The infrastructure is mostly a C backend with Perl serving API and we use these .tt files to show the HTML and .js.tt to serve the Knockout.js code. What is .tt?
A TT file is a Visual Studio Text Template, developed by Microsoft.
Text Template Transformation Toolkit, shortly written as T4, uses the .tt file extension for its source files. It is Microsoft's template-based text generation framework included with Visual Studio.
For more info, see the docs.
If you take a look inside the file, you'll probably notice a lot of logic injecting things. This is because this kind of files are used to generate other files.
As explained in the MS page shared by #Recev Yildiz:
In Visual Studio, a T4 text template is a mixture of text blocks and control logic that can generate a text file.
The control logic is written as fragments of program code in Visual C# or Visual Basic. In Visual Studio 2015 Update 2 and later, you can use C# version 6.0 features in T4 templates directives.
The generated file can be text of any kind, such as a web page, or a resource file, or program source code in any language.
There are two kinds of T4 text templates: run time and design time.
Here's an example of a code I've got from a Entity Framework file, from a ASP.NET Web Application (.NET Framework) project (MVC design):
<## template language="C#" debug="false" hostspecific="true"#>
<## include file="EF6.Utility.CS.ttinclude"#><##
output extension=".cs"#><#
const string inputFile = #"DBModel.edmx";
var textTransform = DynamicTextTransformation.Create(this);
var code = new CodeGenerationTools(this);
var ef = new MetadataTools(this);
var typeMapper = new TypeMapper(code, ef, textTransform.Errors);
var loader = new EdmMetadataLoader(textTransform.Host, textTransform.Errors);
var itemCollection = loader.CreateEdmItemCollection(inputFile);
var modelNamespace = loader.GetModelNamespace(inputFile);
var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef);
var container = itemCollection.OfType<EntityContainer>().FirstOrDefault();
if (container == null)
{
return string.Empty;
}
#>
//------------------------------------------------------------------------------
// <auto-generated>
// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine1")#>
//
// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine2")#>
// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine3")#>
// </auto-generated>
//------------------------------------------------------------------------------
<#
var codeNamespace = code.VsNamespaceSuggestion();
if (!String.IsNullOrEmpty(codeNamespace))
{
#>
namespace <#=code.EscapeNamespace(codeNamespace)#>
{
<#
PushIndent(" ");
}
#>
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
<#
if (container.FunctionImports.Any())
{
#>
using System.Data.Entity.Core.Objects;
using System.Linq;
<#
}
#>
<#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : DbContext
{
public <#=code.Escape(container)#>()
: base("name=<#=container.Name#>")
{
<#
if (!loader.IsLazyLoadingEnabled(container))
{
#>
this.Configuration.LazyLoadingEnabled = false;
<#
}
foreach (var entitySet in container.BaseEntitySets.OfType<EntitySet>())
{
// Note: the DbSet members are defined below such that the getter and
// setter always have the same accessibility as the DbSet definition
if (Accessibility.ForReadOnlyProperty(entitySet) != "public")
{
#>
<#=codeStringGenerator.DbSetInitializer(entitySet)#>
<#
}
}
#>
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
<#
foreach (var entitySet in container.BaseEntitySets.OfType<EntitySet>())
{
#>
<#=codeStringGenerator.DbSet(entitySet)#>
<#
}
foreach (var edmFunction in container.FunctionImports)
{
WriteFunctionImport(typeMapper, codeStringGenerator, edmFunction, modelNamespace, includeMergeOption: false);
}
#>
}
The file was way larger than what you see here. And as you can see, it seems to be a really busy code.
This is the context where the file is placed:
TT stands for - Visual Studio Text Template is a software development tool created by the Microsoft.
Further explanation - TT file contains text block and control logic used for generating new files. To write the Text Template file we can use either - Visual C# or Visual Basic Code
It's mainly used for handling Run Time text generation and source code generation both at once. They're like normal text files and can be viewed in any text editor.

Compiling and Interpreting Packaged Software Assignment - Cant display multilple class outputs

This is a bit involved, and I want to explain this succinctly without making you read a lot, then show the code. I'm not good at that.
Barebones explanation. In this assignment, we are learning, how to compile,interpret in comand prompt, create a package, create a class and sub-classes, import the sub-classes, and execute println commands in all the sub-classes as a single compiled program, and display such in command prompt. I'm missing something, and the subclass println commands don't display when I run GreetingsClass.java, the Superclass. They are all in the same package. The package directory is com.cisp2030.course, and the three Chapters class files exist in a .Chapters folder inside of .course.
First, GreetingsClass.java:
package com.cisp2030.course;
import com.cisp2030.course.Chapters.*;
public class GreetingsClass
{
Chapter1 c1 = new Chapter1();
Chapter2 c2 = new Chapter2();
Chapter3 c3 = new Chapter3();
public static void main(String[] args)
{
System.out.println("$ Greetings, CISP2030!");
System.out.println(c1);
}
}
This is supposed to import and instantiate the variables of the next code contained as Chapter1.class in .Chapters folder.
package com.cisp2030.course.Chapters;
public class Chapter1
{
public Chapter1()
{
System.out.println("Hello from Chapter1!");
}
}
Just imagine that the above code is one of three that range from Chapter1-Chapter3, and they have been compiled by Command Prompt into class files in their respective directory.
The expected output of compiling, interpreting, and running this program in command prompt should be one program which displays all 3-4 println commands. However, at this time, running hte command prompt only displays the one println command. I think this is because I need to sub-class the Chapter classes to GreetingsClass, and having them imported already, somehow direct GreetingsClass to execute the commands of hte Chapters class files, but I don't know how, and I've googled this consistently, and searched through my textbook and am none the wiser. I think I'm missing something in the code itself, but I don't know enough to come up with any ideas. Any help or advice would be greatly appreciated.
Code has been finished:
package com.cisp2030.course;
import com.cisp2030.course.Chapters.*;
public class GreetingsClass
{
public static void main(String[] args)
{
System.out.println("$ Greetings, CISP2030!");
Chapter1 c1 = new Chapter1();
Chapter2 c2 = new Chapter2();
Chapter3 c3 = new Chapter3();
}
}
Does that even compile?
Java doesn't allow static constructors.
public Chapter1() // removed "static"
{
System.out.println("Hello from Chapter1!");
}
c1 is a member of GreetingsClass. In main() you are in a static method, not a method of GreetingsClass and so you can't access it's members. Most obvious solution is to add GreetingsClass greetings = new GreetingsClass(); to main and try to get c1 out of that.

Entity Framework 4.3.1 add-migration error: "model backing the context has changed"

I'm getting an error when trying to run the EF 4.3.1 add-migrations command:
"The model backing the ... context has changed since the database was created".
Here's one sequence that gets the error (although I've tried probably a dozen variants which also all fail)...
1) Start with a database that was created by EF Code First (ie, already contains a _MigrationHistory table with only the InitialCreate row).
2) The app's code data model and database are in-sync at this point (the database was created by CF when the app was started).
3) Because I have four DBContexts in my "Services" project, I didn't run 'enable-migrations' command (it doesn't handle multipe contexts). Instead, I manually created the Migrations folder in the Services project and the Configuration.cs file (included at end of this post). [I think I read this in a post somewhere]
4) With the database not yet changed, and the app stopped, I use the VS EDM editor to make a trivial change to my data model (add one property to an existing entity), and have it generate the new classes (but not modify the database, obviously). I then rebuild the solution and all looks OK (but don't delete the database or restart the app, of course).
5) I run the following PMC command (where "App" is the name of one of the classes in Configuration.cs):
PM> add-migration App_AddTrivial -conf App -project Services -startup Services -verbose
... which fails with the "The model ... has changed. Consider using Code First Migrations..." error.
What am I doing wrong? And does anyone else see the irony in the tool telling me to use what I'm already trying to use ;-)
What are the correct steps for setting-up a solution starting with a database that was created by EF CF? I've seen posts saying to run an initial migration with -ignorechanges, but I've tried that and it doesn't help. Actually, I've spent all DAY testing various permutations, and nothing works!
I must be doing something really stupid, but I don't know what!
Thanks,
DadCat
Configuration.cs:
namespace mynamespace
{
internal sealed class App : DbMigrationsConfiguration
{
public App()
{
AutomaticMigrationsEnabled = false;
MigrationsNamespace = "Services.App.Repository.Migrations";
}
protected override void Seed(.Services.App.Repository.ModelContainer context)
{
}
}
internal sealed class Catalog : DbMigrationsConfiguration<Services.Catalog.Repository.ModelContainer>
{
public Catalog()
{
AutomaticMigrationsEnabled = false;
MigrationsNamespace = "Services.Catalog.Repository.Migrations";
}
protected override void Seed(Services.Catalog.Repository.ModelContainer context)
{
}
}
internal sealed class Portfolio : DbMigrationsConfiguration<Services.PortfolioManagement.Repository.ModelContainer>
{
public Portfolio()
{
AutomaticMigrationsEnabled = false;
MigrationsNamespace = "Services.PortfolioManagement.Repository.Migrations";
}
protected override void Seed(Services.PortfolioManagement.Repository.ModelContainer context)
{
}
}
internal sealed class Scheduler : DbMigrationsConfiguration<.Services.Scheduler.Repository.ModelContainer>
{
public Scheduler()
{
AutomaticMigrationsEnabled = false;
MigrationsNamespace = "Services.Scheduler.Repository.Migrations";
}
protected override void Seed(Services.Scheduler.Repository.ModelContainer context)
{
}
}
}
When using EF Migrations you should have one data context per database. I know that it can grow really large, but by trying to split it you will run into several problems. One is the migration issue that you are experiencing. Later on you will probably be facing problems when trying to make queries joining tables from the different contexts. Don't go that way, it's against how EF is designed.

Coded UI Test Builder records similar classes, creating numerous classes in UIMap

Is there a way to force Coded UI Test Builder to use it’s already recorded classes?
It creates very similar classes even within single recording session.
E.g. the only difference in URL in two classes generated below.
I’d like to reuse code – no sense to have such duplications. Anything besides manual cleanup?
public class UISearchResultsOracleDocument : HtmlDocument
{
public UISearchResultsOracleDocument(UITestControl searchLimitContainer) :
base(searchLimitContainer)
{
#region Search Criteria
this.SearchProperties[HtmlDocument.PropertyNames.Id] = null;
this.SearchProperties[HtmlDocument.PropertyNames.RedirectingPage] = "False";
this.SearchProperties[HtmlDocument.PropertyNames.FrameDocument] = "False";
this.FilterProperties[HtmlDocument.PropertyNames.Title] = "Search Results : " + EnterSearchedTextParams.UISearchEditText;
this.FilterProperties[HtmlDocument.PropertyNames.AbsolutePath] = "/project/Pages/results.aspx";
this.FilterProperties[HtmlDocument.PropertyNames.PageUrl] = "http://my.url.com:123/project/Pages/results.aspx?k=Oracle";
this.WindowTitles.Add("Search Results : Oracle");
#endregion
}
// ...
}
//And almost duplicate
public class UISearchResultsOracleDocument1 : HtmlDocument
{
public UISearchResultsOracleDocument1(UITestControl searchLimitContainer) :
base(searchLimitContainer)
{
#region Search Criteria
this.SearchProperties[HtmlDocument.PropertyNames.Id] = null;
this.SearchProperties[HtmlDocument.PropertyNames.RedirectingPage] = "False";
this.SearchProperties[HtmlDocument.PropertyNames.FrameDocument] = "False";
this.FilterProperties[HtmlDocument.PropertyNames.Title] = "Search Results : Oracle";
this.FilterProperties[HtmlDocument.PropertyNames.AbsolutePath] = "/project/Pages/results.aspx";
this.FilterProperties[HtmlDocument.PropertyNames.PageUrl] = "http://my.url.com:123/project/Pages/results.aspx?k=Oracle&start1=1";
this.WindowTitles.Add("Search Results : Oracle");
#endregion
}
// ...
}
Thus, question is how to eliminate duplication?
Any hints to decrease number of new classes in UIMap?
Thanks
Yuri
try going thr below links..
http://blogs.msdn.com/b/gautamg/archive/2009/12/18/why-is-coded-ui-test-generated-code-not-a-straight-line-code.aspx
http://blogs.msdn.com/b/gautamg/archive/2009/12/21/understanding-the-code-generated-by-coded-ui-test-part-2.aspx
from above links:
The guidelines for code generation
that we came up with (some based on
the feedback received) was -
Encourage reusability of the test code. This is both for productivity
and better maintenance.
Make customization of code easier for common scenarios like Data
Driving.
Give full control on the code for advance operation.
You can always hand code the same.but is much more tricker than recording it.

Resources