我使用 VS2012 设计 UML 图,我使用 T4 生成自定义类和接口。
我使用 TFS 作为源代码管理器。
但是从昨天开始我收到一个错误并且没有生成代码。
5/13/2013 8:18:59 AM: Code generation or text transformation started.
5/13/2013 8:19:51 AM: Errors encountered in 'ClassTemplate.t4' while generating code for 'Andish.CSS.Modeling.UMLDiagram::Model::Andish.CSS.Domain::BusinessDomain::Calculator::Grou pPreCalculatingResult' - (Class).
5/13/2013 8:19:58 AM: Code generation complete. Errors: 1. Warnings: 0.
5/13/2013 8:19:58 AM: Unable to write log file: F:\Andish\AndishmandFramWork\Modeling\Andish.CSS.Modeling.UMLDiagram\CodeGeneration.Log.xml - Access to the path 'F:\Andish\AndishmandFramWork\Modeling\Andish.CSS.Modeling.UMLDiagram\CodeGeneration.Log.xm l' is denied.
这是我 VS2012 的图片
我得到一个错误,比如 down :
Error 44 Errors were generated when initializing the transformation object. The transformation will not be run. The following Exception was thrown:
System.NullReferenceException: Object reference not set to an instance of an object.
at Microsoft.VisualStudio.TextTemplating5DC31BF3C568533E6A5135685CF1D48CEE628C2D066E9F2E28996B 26FB846E02D5A1B9165E6B13EEEEA7BBA99E06465E913189341F3D59CE816F2CEB52FAEBA8.GeneratedTextTra nsformation.AppliesToElement()
at Microsoft.VisualStudio.ArchitectureTools.TextTransformation.ModelingTextTransformation.Init ialize()
at CallSite.Target(Closure , CallSite , Object )
at System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid1[T0](CallSite site, T0 arg0)
at Microsoft.VisualStudio.TextTemplating.TransformationRunner.PerformTransformation()
我使用像 down 一样的 t4 类
<#@ Include File="TemplateHeader.t4" #>
<#@ Modeling ElementType="Microsoft.VisualStudio.Uml.Classes.IClass" Processor="ModelingProcessor" ApplyStereotypes="CSharp" #>
<#@ Import Namespace="Microsoft.VisualStudio.Uml.AuxiliaryConstructs" #>
<#@ Import Namespace="Microsoft.VisualStudio.Uml.Classes" #>
<#@ Import Namespace="Microsoft.VisualStudio.ArchitectureTools.Extensibility.Uml" #>
<#@ Include File="CSharpCommentHelpers.t4" #>
<#@ Include File="CSharpHelpers.t4" #>
<#@ Output Extension=".cs" #>
<#
WriteAutoGeneratedWarningHeader();
WriteLine("using System.Runtime.Serialization;");
WriteLine("using System.ServiceModel;");
string classNamespace = GetNamespace(this.Element.Namespace);
if(!string.IsNullOrEmpty(classNamespace))
{
#>
namespace <#= classNamespace #>
{
<#
PushIndent("\t");
}
WriteUsingStatements(this.Element);
WriteLine("");
System.Globalization.PersianCalendar PDate=new System.Globalization.PersianCalendar();
DateTime BeforDate=new DateTime(PDate.GetYear(System.DateTime.Now),PDate.GetMonth(System.DateTime.Now),PDate.GetDayOfMonth(System.DateTime.Now),PDate.GetHour(System.DateTime.Now),PDate.GetMinute(System.DateTime.Now),PDate.GetSecond(System.DateTime.Now));
string Date=String.Format("{0:yyyy/MM/dd HH:mm:ss}",BeforDate);
WriteSinglelineDocComment("Author","Name = \"T4Generator\"","");
WriteSinglelineDocComment("CreateDate","Date = \"" + Date+"\"","");
WriteSinglelineDocComment("LastModifyUser","Name = \"T4Generator\"","");
WriteSinglelineDocComment("LastModifyDate","Date = \"" + Date+"\"","");
WriteSinglelineDocComment("Version","Number = \"1\"","");
WriteSinglelineDocComment("Release","Number = \"1\"","");
WriteSummaryComment(this.Element.Description);
WriteTemplateTypeParameterComments(TemplateParameterNameDescriptionPairs(this.Element));
//WriteLine("[ServiceErrorBehaviour(typeof(HttpErrorHandler))]");
foreach(var comment in this.Element.GetModelStore().AllInstances<IComment>().Where(c => c.AnnotatedElements.Contains(this.Element)))
{
WriteRemarksComment(comment.Body);
}
#>
<#
WriteClassClrAttributes(this.Element);
#>
<#= ClassVisibility(this.Element) #><#= ClassUnsafeOption(this.Element) #><#= ClassStaticOption(this.Element) #><#= ClassAbstractOption(this.Element) #><#= ClassSealedOption(this.Element) #><#= ClassPartialOption(this.Element) #>class <#= ClassifierName(this.Element) #><#= ImplementedAndInheritedList(this.Element) #><# WriteClassifierConstraintOption(this.Element); #>
{
<#
PushIndent("\t");
// Write Attributes
var ownedAttributes = this.Element.OwnedAttributes;
foreach(IProperty attribute in ownedAttributes)
{
WriteSummaryComment(attribute.Description);
WriteClassUmlPropertyDefinition(attribute);
WriteLine("");
}
#>
<#
// Write Associations
var navigableOwnedEnds = GetNavigableOwnedEnds(this.Element, ownedAttributes);
foreach(IProperty ownedEnd in navigableOwnedEnds)
{
WriteSummaryComment(ownedEnd.OwningAssociation.Description);
WriteSummaryComment(ownedEnd.Description);
WriteClassUmlPropertyDefinition(ownedEnd);
WriteLine("");
}
#>
<#
// Write Operations
foreach(IOperation operation in this.Element.OwnedOperations)
{
WriteSinglelineDocComment("Author","Name = \"T4Generator\"","");
WriteSinglelineDocComment("CreateDate","Date = \"" + Date+"\"","");
WriteSinglelineDocComment("LastModifyUser","Name = \"T4Generator\"","");
WriteSinglelineDocComment("LastModifyDate","Date = \"" + Date+"\"","");
WriteSinglelineDocComment("Version","Number = \"1\"","");
WriteSinglelineDocComment("Release ","Number = \"1\"","");
WriteSummaryComment(operation.Description + GetCommentOfGlobalMethod(operation.Name));
foreach (IParameter parameter in operation.OwnedParameters.Where(p => p.Direction != ParameterDirectionKind.Return))
{
WriteParameterComment(parameter.Name, parameter.Description);
}
WriteSinglelineDocComment("returns","","");
if(GetStereotype(operation) == "method")
{
WriteMethodClrAttributes(operation);
if(IsConstructor(operation) || IsDestructor(operation))
{
#>
<#= MethodVisibility(operation) #><#= operation.Name #>(<# WriteMethodParameterList(operation); #>)
{
}
<#
}
else
{
#>
<#= MethodVisibility(operation) #><#= MethodUnsafeOption(operation) #><#= OperationStaticOption(operation) #><#= ClassMethodOverloadOption(operation, this.Element) #><#= MethodPartialOption(operation) #><#= MethodType(operation) #> <#= operation.Name #>(<# WriteMethodParameterList(operation); #>)<# WriteClassMethodBody(operation); #>
<#
}
WriteLine("");
}
else if(GetStereotype(operation) == "indexer")
{
WriteIndexerClrAttributes(operation);
#>
<#= IndexerVisibility(operation) #><#= IndexerUnsafeOption(operation) #><#= OperationStaticOption(operation) #><#= ClassIndexerOverloadOption(operation, this.Element) #><#= IndexerType(operation) #> this[<# WriteIndexerParameterList(operation); #>]
{
<#
PushIndent("\t");
#>
<#= IndexerGetVisibility(operation) #>get<# WriteClassIndexerAccessorBody(operation); #>
<#= IndexerSetVisibility(operation) #>set<# WriteClassIndexerAccessorBody(operation); #>
<#
PopIndent();
#>
}
<#
WriteLine("");
}
}
PopIndent();
#>
}
<#
ClearIndent();
if(!string.IsNullOrEmpty(classNamespace))
{
#>
}
<# } #>
<#+
#region Inheritance
/// <summary>
/// Gets the implemented and inherited types of the given class.
/// </summary>
/// <param name="aClass">The given class</param>
/// <returns>implementedAndInherted types</returns>
private static string ImplementedAndInheritedList(IClass aClass)
{
var list = ImplementedAndInheritedTypes(aClass);
if(list.Any())
{
return " : " + string.Join(", ", list.Select(t => ElementType(t)));
}
else
{
return string.Empty;
}
}
#endregion Inheritance
#region Polymorphism
/// <summary>
/// Gets the overload option of the indexer.
/// </summary>
/// <param name="operation">The operation</param>
/// <param name="owner">The class</param>
/// <returns>The overload option for the operation</returns>
private static string ClassIndexerOverloadOption(IOperation operation, IClass owner)
{
return ClassOperationOverloadOption(operation, owner);
}
/// <summary>
/// Gets the overload option of the method.
/// </summary>
/// <param name="operation">The operation</param>
/// <param name="owner">The class</param>
/// <returns>The overload option for the operation</returns>
private static string ClassMethodOverloadOption(IOperation operation, IClass owner)
{
if(string.IsNullOrEmpty(MethodPartialOption(operation)))
{
return ClassOperationOverloadOption(operation, owner);
}
else
{
return string.Empty;
}
}
/// <summary>
/// Gets the overload option of the operation.
/// </summary>
/// <param name="operation">The operation</param>
/// <param name="owner">The class</param>
/// <returns>The overload option for the operation</returns>
private static string ClassOperationOverloadOption(IOperation operation, IClass owner)
{
string overload = string.Empty;
if(!string.IsNullOrEmpty(OperationAbstractOption(operation)))
{
overload += "abstract ";
}
else if(IsInheritedMember(operation, owner))
{
overload += "override ";
if(!string.IsNullOrEmpty(OperationSealedOption(operation)))
{
overload += "sealed ";
}
}
//دلیل کامنت شدن حذف کلمه virctual از تعریف متد
// else if(IsOverridable(operation, owner))
// {
// overload += "virtual ";
// }
return overload;
}
/// <summary>
/// Gets the overload option of the property.
/// </summary>
/// <param name="property">The property</param>
/// <param name="owner">The class</param>
/// <returns>The overload option for the property</returns>
private static string ClassPropertyOverloadOption(IProperty property, IClass owner)
{
string overload = string.Empty;
if(IsInheritedMember(property, owner))
{
overload = "override ";
if(!string.IsNullOrEmpty(PropertySealedOption(property)))
{
overload += "sealed ";
}
}
else if(IsOverridable(property, owner))
{
overload += "virtual ";
}
return overload;
}
/// <summary>
/// Checks if the operation is overridable.
/// </summary>
/// <param name="operation">The operation</param>
/// <param name="owner">The class</param>
/// <returns>true if the operation is an inherited member.</returns>
private static bool IsOverridable(IOperation operation, IClass owner)
{
bool isPrivate = MethodVisibility(operation) == "private " || IndexerVisibility(operation) == "private ";
return !isPrivate && string.IsNullOrEmpty(OperationStaticOption(operation)) && string.IsNullOrEmpty(OperationSealedOption(operation)) && HasVirtualMembers(owner);
}
/// <summary>
/// Checks if the property is overridable.
/// </summary>
/// <param name="property">The property</param>
/// <param name="owner">The class</param>
/// <returns>true if the property is an inherited member.</returns>
private static bool IsOverridable(IProperty property, IClass owner)
{
bool isPrivate = FieldVisibility(property) == "private " || PropertyVisibility(property) == "private ";
return !isPrivate && string.IsNullOrEmpty(AttributeStaticOption(property)) && string.IsNullOrEmpty(PropertySealedOption(property)) && HasVirtualMembers(owner);
}
/// <summary>
/// Checks if the classifier could have virtual memebers.
/// </summary>
/// <param name="aClass">The class</param>
/// <returns>true if the property is an inherited member.</returns>
private static bool HasVirtualMembers(IClass aClass)
{
return string.IsNullOrEmpty(ClassSealedOption(aClass)) && string.IsNullOrEmpty(ClassStaticOption(aClass));
}
/// <summary>
/// Checks if the property is an inherited member.
/// </summary>
/// <param name="property">The property</param>
/// <param name="owner">The owner class of the property</param>
/// <returns>true if the property is an inherited member.</returns>
private static bool IsInheritedMember(IProperty property, IClass owner)
{
var types = ImplementedOrInheritedTypes(owner);
foreach(IType type in types)
{
IClassifier baseClassifier = type as IClassifier;
if(baseClassifier != null)
{
ITemplateBinding templateBinding = GetTemplateBinding(baseClassifier);
IClassifier bindingClassifier = GetBindingClassifier(templateBinding);
if(bindingClassifier != null)
{
baseClassifier = bindingClassifier;
}
foreach(IProperty propertyInBase in GetOwnedProperties(baseClassifier))
{
bool isInheritedMember = IsInheritedMember(propertyInBase, property, templateBinding);
if(isInheritedMember)
{
return true;
}
}
}
}
return false;
}
/// <summary>
/// Checks if the property is an inherited member.
/// </summary>
/// <param name="propertyInBase">The property in base</param>
/// <param name="propertyInSubClass">The property in subclass</param>
/// <param name="templateBinding">The template binding</param>
/// <returns>true if the property in the subclass is an inherited member; false if it is not or the base is an interface</returns>
private static bool IsInheritedMember(IProperty propertyInBase, IProperty propertyInSubClass, ITemplateBinding templateBinding)
{
var propertyInBaseOwner = propertyInBase.Owner;
if(propertyInBaseOwner is IAssociation)
{
propertyInBaseOwner = ((IAssociation)propertyInBaseOwner).SourceElement;
}
if(propertyInBaseOwner is IInterface)
{
return false;
}
else if(propertyInBaseOwner is IClass)
{
bool isInheritedProperty = IsInheritedProperty(propertyInSubClass, propertyInBase, templateBinding);
bool isOverridable = IsOverridable(propertyInBase, (IClass)propertyInBaseOwner);
return isInheritedProperty && isOverridable;
}
return false;
}
/// <summary>
/// Checks if the operation is an inherited member.
/// </summary>
/// <param name="operation">The operation</param>
/// <param name="owner">The owning class of the operation</param>
/// <returns>true if the operation is an inherited member.</returns>
private static bool IsInheritedMember(IOperation operation, IClass owner)
{
var types = ImplementedOrInheritedTypes(owner);
foreach(IType type in types)
{
IClassifier baseClassifier = type as IClassifier;
if(baseClassifier != null)
{
ITemplateBinding templateBinding = GetTemplateBinding(baseClassifier);
IClassifier bindingClassifier = GetBindingClassifier(templateBinding);
if(bindingClassifier != null)
{
baseClassifier = bindingClassifier;
}
foreach(IOperation operationInBase in GetOwnedOperations(baseClassifier))
{
bool isInheritedMember = IsInheritedMember(operationInBase, operation, templateBinding);
if(isInheritedMember)
{
return true;
}
}
}
}
return false;
}
/// <summary>
/// Checks if the operation is an inherited member.
/// </summary>
/// <param name="operationInBase">The operation in base</param>
/// <param name="operationInSubClass">The operation in the subclass</param>
/// <param name="templateBinding">The template binding</param>
/// <returns>true if the operation in the subclass is an inherited member; false if it is not or the base is an interface</returns>
private static bool IsInheritedMember(IOperation operationInBase, IOperation operationInSubClass, ITemplateBinding templateBinding)
{
var operationInBaseOwner = operationInBase.Owner;
if(operationInBaseOwner is IAssociation)
{
operationInBaseOwner = ((IAssociation)operationInBaseOwner).SourceElement;
}
if(operationInBaseOwner is IInterface)
{
return false;
}
else if(operationInBaseOwner is IClass)
{
bool isInheritedOperation = IsInheritedOperation(operationInSubClass, operationInBase, templateBinding);
bool isOverridable = IsOverridable(operationInBase, (IClass)operationInBaseOwner);
return isInheritedOperation && isOverridable;
}
return false;
}
/// <summary>
/// Checks if the operation in subclass is inherited from the operation in base.
/// </summary>
/// <param name="operationInSubClass">The operation in subClass</param>
/// <param name="operationInBase">The operation in base</param>
/// <param name="templateBinding">The template binding</param>
/// <returns>if operation in subClass is inherited from the operation in base.</returns>
private static bool IsInheritedOperation(IOperation operationInSubClass, IOperation operationInBase, ITemplateBinding templateBinding)
{
if(templateBinding == null)
{
return operationInSubClass.Signature == operationInBase.Signature;
}
if(operationInSubClass.Name != operationInBase.Name)
{
return false;
}
var subClassOperationOwnedParametersInOrder = GetOwnedParametersInOrder(operationInSubClass);
var baseClassOperationOwnedParametersInOrder = GetOwnedParametersInOrder(operationInBase);
int numOfSubClassOperationOwnedParameters = subClassOperationOwnedParametersInOrder.Count();
if(numOfSubClassOperationOwnedParameters != baseClassOperationOwnedParametersInOrder.Count())
{
return false;
}
var parameterSubstitutions = templateBinding.ParameterSubstitutions;
// find the newly defined template parameters
var baseClassifier = (IClassifier)operationInBase.Owner;
var subClassifier = (IClassifier)operationInSubClass.Owner;
var subClassNewlyDefinedTemplateParameterNames = GetNewlyDefinedTemplateParameterNamesInSubClass(baseClassifier, subClassifier, parameterSubstitutions);
for(int i=0; i < numOfSubClassOperationOwnedParameters; i++)
{
var subClassOperationOwnedParameter = subClassOperationOwnedParametersInOrder.ElementAt(i);
var baseClassOperationOwnedParameter = baseClassOperationOwnedParametersInOrder.ElementAt(i);
if(subClassOperationOwnedParameter.Direction != baseClassOperationOwnedParameter.Direction)
{
return false;
}
bool isParameterInBaseEnumerable = IsEnumerable(baseClassOperationOwnedParameter);
bool isParameterInSubClassEnumerable = IsEnumerable(subClassOperationOwnedParameter);
if(isParameterInBaseEnumerable != isParameterInSubClassEnumerable)
{
return false;
}
if(!OneTypeOverridesTheOther(baseClassOperationOwnedParameter.Type, subClassOperationOwnedParameter.Type, parameterSubstitutions, subClassNewlyDefinedTemplateParameterNames))
{
return false;
}
}
return true;
}
/// <summary>
/// Gets the owned parameters in order: first is the parameter of return type, and then the rest of the parameters.
/// </summary>
/// <param name="operation">The operation</param>
/// <returns>List of owned parameters in order</returns>
private static List<IParameter> GetOwnedParametersInOrder(IOperation operation)
{
var orderedSet = Enumerable.Union<IParameter>(operation.OwnedParameters.Where(parameter => parameter.Direction == ParameterDirectionKind.Return), operation.OwnedParameters.Where(parameter => parameter.Direction != ParameterDirectionKind.Return));
return orderedSet.ToList();
}
/// <summary>
/// Checks if the two type names are equal with considering of the template binding substitutions.
/// </summary>
/// <param name="propertyInSubClass">The property in subClass</param>
/// <param name="propertyInBase">The property in base</param>
/// <param name="templateBinding">The template binding</param>
/// <returns>if property in subClass is inherited from the property in base.</returns>
.........
我无法复制 T4 模板的所有代码,因为这篇文章中的最大长度是 30000 个字符。