网上看到有人使用T4来生成代码,发现这个东西自己没有接触过,因此google了一下,学习了一下相关的知识。

 现把自己学习的过程记录一下:

下面的代码主要是通过T4模板生成数据库表实体对象的过程。

1、首先我们需要实现 ITextTemplatingEngineHost 接口的类。该类存在"Microsoft.VisualStudio.TextTemplating.dll"中,因此我们需要在项目工程中引用此Dll文件。

下面是代码:

 [Serializable]
    
public class TableHost : Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost {
        
private string _namespace = "JXDModel";
        
        
public string Namespace {
            
get { return _namespace; }
            
set { _namespace = value; }
        }

        
protected string _classname = "tablename";
        
public string Classname {
            
get { return _classname; }
            
set { _classname = value; }
        }
        
protected DataTable _dt = new DataTable();
        
public DataTable Dt {
            
get { return _dt; }
            
set { _dt = value; }
        }

        
protected string _templateFile = "";
        
public string TemplateFile {
            
get { return _templateFile; }
            
set { _templateFile = value; }
        }
        
protected string _fileExtension = ".cs";
        
public string FileExtension {
            
get { return _fileExtension; }
            
set { _fileExtension = value; }
        }
        
public IList<string> StandardAssemblyReferences {
            
get {
                
return new string[]
            {
                
typeof(System.Uri).Assembly.Location,
                
typeof(TableHost).Assembly.Location,
                
typeof(DbType).Assembly.Location,
                
typeof(XmlDataDocument).Assembly.Location,
                
typeof(System.Xml.Serialization.XmlSchemas).Assembly.Location,
                
typeof(System.AppDomain ).Assembly.Location 
            };
            }
        }
        
public IList<string> StandardImports {
            
get {
                
return new string[]
        { 
            
"System",
            
"System.Data",
            
"System.IO",
            
"System.Xml",
            
"System.Xml.Serialization",
            
"System.Text",
            
"windows2008",
            
"System.Data.Common",
            
"System.Collections",
            
"System.Collections.Generic",
            
"System.Collections.Specialized"
        };
            }
        }

        
public object GetHostOption(string optionName) {
            
object returnObject;
            
switch (optionName) {
                
case "CacheAssemblies":
                    returnObject 
= true;
                    
break;
                
default:
                    returnObject 
= null;
                    
break;
            }
            
return returnObject;
        }

        
public void SetFileExtension(string extension) {
            _fileExtension 
= extension;
        }

        
private System.Text.Encoding _fileEncodingValue = System.Text.Encoding.UTF8;
        
public void SetOutputEncoding(System.Text.Encoding encoding, bool fromOutputDirective) {
            _fileEncodingValue 
= encoding;
        }

        
private CompilerErrorCollection _errorsValue;
        
public CompilerErrorCollection Errors {
            
get { return _errorsValue; }
        }

        
public void LogErrors(CompilerErrorCollection errors) {
            _errorsValue 
= errors;
        }
        
public string ResolvePath(string fileName) {
            
return fileName;
        }
        
public bool LoadIncludeText(string requestFileName, out string content, out string location) {
            content 
= System.String.Empty;
            location 
= System.String.Empty;

            
//If the argument is the fully qualified path of an existing file,
            
//then we are done.
            
//----------------------------------------------------------------
            if (File.Exists(requestFileName)) {
                content 
= File.ReadAllText(requestFileName);
                
return true;
            }

            
//This can be customized to search specific paths for the file.
                
//This can be customized to accept paths to search as command line
                
//arguments.
                
//----------------------------------------------------------------
            else {
                
return false;
            }
        }
        
public string ResolveAssemblyReference(string assemblyReference) {
            
if (File.Exists(assemblyReference)) {
                
return assemblyReference;
            }
            
string candidate = Path.Combine(Path.GetDirectoryName(this.TemplateFile), assemblyReference);
            
if (File.Exists(candidate)) {
                
return candidate;
            }
            
return "";
        }
        
public Type ResolveDirectiveProcessor(string processorName) {
            
throw new Exception("Directive Processor not found");
        }

        
public string ResolveParameterValue(string directiveId, string processorName, string parameterName) {
            
if (directiveId == null) {
                
throw new ArgumentNullException("the directiveId cannot be null");
            }
            
if (processorName == null) {
                
throw new ArgumentNullException("the processorName cannot be null");
            }
            
if (parameterName == null) {
                
throw new ArgumentNullException("the parameterName cannot be null");
            }

            
//Code to provide "hard-coded" parameter values goes here.
            
//This code depends on the directive processors this host will interact with.

            
//If we cannot do better, return the empty string.
            return String.Empty;
        }
        
public AppDomain ProvideTemplatingAppDomain(string content) {
            
//This host will provide a new application domain each time the 
            
//engine processes a text template.
            
//-------------------------------------------------------------
            return AppDomain.CreateDomain("Generation App Domain");

            
//This could be changed to return the current appdomain, but new 
            
//assemblies are loaded into this AppDomain on a regular basis.
            
//If the AppDomain lasts too long, it will grow indefintely, 
            
//which might be regarded as a leak.

            
//This could be customized to cache the application domain for 
            
//a certain number of text template generations (for example, 10).

            
//This could be customized based on the contents of the text 
            
//template, which are provided as a parameter for that purpose.
        }
    }

相关文章:

  • 2021-09-14
  • 2021-09-16
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-01-04
  • 2022-02-01
猜你喜欢
  • 2022-12-23
  • 2021-10-09
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案