我正在使用.Net Core 1.1
我想在Visual Studio 2017 15.1中使用T4生成一些代码
MultipleOutputHelper.ttinclude:
<#@ assembly name="System.Core"#>
<#@ assembly name="System.Data.Linq"#>
<#@ assembly name="EnvDTE"#>
<#@ assembly name="System.Xml"#>
<#@ assembly name="System.Xml.Linq"#>
<#@ import namespace="System.Collections.Generic"#>
<#@ import namespace="System.IO"#>
<#@ import namespace="System.Text"#>
<#@ import namespace="EnvDTE" #>
<#@ import namespace="Microsoft.VisualStudio.TextTemplating"#>
<#+
// https://github.com/damieng/DamienGKit/tree/master/T4/MultipleOutputHelper
// http://damieng.com/blog/2009/11/06/multiple-outputs-from-t4-made-easy-revisited
// Manager class records the various blocks so it can split them up
class Manager {
private class Block {
public string Name;
public int Start, Length;
public bool IncludeInDefault;
}
private Block currentBlock;
private readonly List<Block> files = new List<Block>();
private readonly Block footer = new Block();
private readonly Block header = new Block();
private readonly ITextTemplatingEngineHost host;
private readonly StringBuilder template;
protected readonly List<string> generatedFileNames = new List<string>();
public static Manager Create(ITextTemplatingEngineHost host, StringBuilder template) {
return (host is IServiceProvider) ? new VSManager(host, template) : new Manager(host, template);
}
public void StartNewFile(string name) {
if (name == null)
throw new ArgumentNullException(nameof(name));
CurrentBlock = new Block { Name = name };
}
public void StartFooter(bool includeInDefault = true) {
CurrentBlock = footer;
footer.IncludeInDefault = includeInDefault;
}
public void StartHeader(bool includeInDefault = true) {
CurrentBlock = header;
header.IncludeInDefault = includeInDefault;
}
public void EndBlock() {
if (CurrentBlock == null)
return;
CurrentBlock.Length = template.Length - CurrentBlock.Start;
if (CurrentBlock != header && CurrentBlock != footer)
files.Add(CurrentBlock);
currentBlock = null;
}
public virtual void Process(bool split, bool sync = true) {
if (!split) return;
EndBlock();
var headerText = template.ToString(header.Start, header.Length);
var footerText = template.ToString(footer.Start, footer.Length);
var outputPath = Path.GetDirectoryName(host.TemplateFile);
files.Reverse();
if (!footer.IncludeInDefault)
template.Remove(footer.Start, footer.Length);
foreach(var block in files) {
var fileName = Path.Combine(outputPath, block.Name);
var content = headerText + template.ToString(block.Start, block.Length) + footerText;
generatedFileNames.Add(fileName);
CreateFile(fileName, content);
template.Remove(block.Start, block.Length);
}
if (!header.IncludeInDefault)
template.Remove(header.Start, header.Length);
}
protected virtual void CreateFile(string fileName, string content) {
if (IsFileContentDifferent(fileName, content))
File.WriteAllText(fileName, content, Encoding.UTF8);
}
public virtual string GetCustomToolNamespace(string fileName) {
return null;
}
public virtual string DefaultProjectNamespace {
get { return null; }
}
protected bool IsFileContentDifferent(string fileName, string newContent) {
return !(File.Exists(fileName) && File.ReadAllText(fileName) == newContent);
}
private Manager(ITextTemplatingEngineHost host, StringBuilder template) {
this.host = host;
this.template = template;
}
private Block CurrentBlock {
get { return currentBlock; }
set {
if (CurrentBlock != null)
EndBlock();
if (value != null)
value.Start = template.Length;
currentBlock = value;
}
}
private class VSManager: Manager {
private readonly ProjectItem templateProjectItem;
private readonly DTE dte;
private readonly Action<string> checkOutAction;
private readonly Action<List<string>> projectSyncAction;
public override string DefaultProjectNamespace {
get {
return templateProjectItem.ContainingProject.Properties.Item("DefaultNamespace").Value.ToString();
}
}
public override string GetCustomToolNamespace(string fileName) {
return dte.Solution.FindProjectItem(fileName).Properties.Item("CustomToolNamespace").Value.ToString();
}
public override void Process(bool split, bool sync) {
if (templateProjectItem.ProjectItems == null)
return;
base.Process(split, sync);
if (sync)
projectSyncAction.EndInvoke(projectSyncAction.BeginInvoke(generatedFileNames, null, null));
}
protected override void CreateFile(string fileName, string content) {
if (IsFileContentDifferent(fileName, content)) {
CheckoutFileIfRequired(fileName);
File.WriteAllText(fileName, content, Encoding.UTF8);
}
}
internal VSManager(ITextTemplatingEngineHost host, StringBuilder template)
: base(host, template) {
var hostServiceProvider = (IServiceProvider)host;
dte = (DTE) hostServiceProvider?.GetService(typeof(DTE)) ?? throw new ArgumentNullException("Could not obtain IServiceProvider");
if (dte == null)
throw new ArgumentNullException("Could not obtain DTE from host");
templateProjectItem = dte.Solution.FindProjectItem(host.TemplateFile);
checkOutAction = fileName => dte.SourceControl.CheckOutItem(fileName);
projectSyncAction = keepFileNames => ProjectSync(templateProjectItem, keepFileNames);
}
private static void ProjectSync(ProjectItem templateProjectItem, List<string> keepFileNames) {
var keepFileNameSet = new HashSet<string>(keepFileNames);
var projectFiles = new Dictionary<string, ProjectItem>();
var originalFilePrefix = Path.GetFileNameWithoutExtension(templateProjectItem.FileNames[0]) + ".";
foreach (ProjectItem projectItem in templateProjectItem.ProjectItems)
projectFiles.Add(projectItem.FileNames[0], projectItem);
// Remove unused items from the project
foreach (var pair in projectFiles)
if (!keepFileNames.Contains(pair.Key) && !(Path.GetFileNameWithoutExtension(pair.Key) + ".").StartsWith(originalFilePrefix))
pair.Value.Delete();
// Add missing files to the project
foreach(var fileName in keepFileNameSet)
if (!projectFiles.ContainsKey(fileName))
templateProjectItem.ProjectItems.AddFromFile(fileName);
}
private void CheckoutFileIfRequired(string fileName) {
var sc = dte.SourceControl;
if (sc != null && sc.IsItemUnderSCC(fileName) && !sc.IsItemCheckedOut(fileName))
checkOutAction.EndInvoke(checkOutAction.BeginInvoke(fileName, null, null));
}
}
}
#>
CreatingBusinessComponentsT4.txt:
<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ include file="MultipleOutputHelper.ttinclude" #>
<#@ assembly name="$(SolutionDir)Smartiz3.Data\bin\Debug\Smartiz3.Data.dll" #>
<#@ import namespace="Smartiz3.Data" #>
// By Mohammad Dayyan
<#
var manager = Manager.Create(Host, GenerationEnvironment);
var @namespace = "Smartiz3.Data";
var assembly = typeof(Smartiz3.Data.Color).Assembly;
var allEntityTypes = assembly.GetTypes().Where(t => t.IsClass && t.Namespace == @namespace).ToArray();
foreach (var entity in allEntityTypes)
{
var entityName = string.Format("{0}{1}", entity.Name[0].ToString().ToLower(), entity.Name.Remove(0,1));
manager.StartNewFile(entity.Name + "BusinessComponent.cs");
#>
using Smartiz3.Business;
namespace Smartiz3.BusinessComponent
{
public class <#= entity.Name #>BusinessComponent : BaseBusinessComponent
{
private readonly <#= entity.Name #>BusinessObject _<#= entityName #>BusinessObject;
public <#= entity.Name #>BusinessComponent(<#= entity.Name #>BusinessObject <#= entityName #>BusinessObject)
{
_<#= entityName #>BusinessObject = <#= entityName #>BusinessObject;
}
public BusinessObject<<#= entity.Name #>, int> BusinessObject => _<#= entityName #>BusinessObject;
}
}<#
manager.EndBlock();
}
#>
<# manager.Process(true); #>
我刚刚使用上面的文件在.Net 4.6.2中生成代码,一切正常,但在.Net Core中我收到以下错误:
错误:
Severity Code Description Project File Line Suppression State
Error Running transformation: System.IO.FileNotFoundException: Could not load file or assembly 'System.Runtime, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
File name: 'System.Runtime, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
at Microsoft.VisualStudio.TextTemplating5D169A44428EC29244069AAD45E449C1543F4B7B59370718992CE3B48758ABBC59FA6B5E2E3A51DF677FEEC8725FA416A706310BDCF6326AC2BD2FD2C19339F3.GeneratedTextTransformation.TransformText()
at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
at CallSite.Target(Closure , CallSite , Object )
at Microsoft.VisualStudio.TextTemplating.TransformationRunner.PerformTransformation()
WRN: Assembly binding logging is turned OFF.
To enable assembly bind failure logging, set the registry value [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1.
Note: There is some performance penalty associated with assembly bind failure logging.
To turn this feature off, remove the registry value [HKLM\Software\Microsoft\Fusion!EnableLog]. BusinessComponent D:\...\CreatingBusinessComponentsT4.tt 1
我安装了以下软件包,但没有任何改变:
System.IO
4.3
System.IO.FileSystem
4.3
我该如何解决?