private static bool DefineResourceFetchingProperty(string propertyName, string resourceName, ResourceData resourceData, CodeTypeDeclaration resourceClass, bool internalClass, bool useStatic) { CodeMethodReturnStatement propertyReturnStatement; CodeMemberProperty resourceProperty = new CodeMemberProperty(); resourceProperty.Name = propertyName; resourceProperty.HasGet = true; resourceProperty.HasSet = false; Type resourceDataType = resourceData.Type; if (null == resourceDataType) return false; if (typeof(MemoryStream) == resourceDataType) resourceDataType = typeof(UnmanagedMemoryStream); while (!resourceDataType.IsPublic) resourceDataType = resourceDataType.BaseType; CodeTypeReference resourceDataTypeReference = new CodeTypeReference(resourceDataType); resourceProperty.Type = resourceDataTypeReference; /*if (internalClass) resourceProperty.Attributes = MemberAttributes.Assembly; else*///Ð resourceProperty.Attributes = MemberAttributes.Public; if (useStatic) resourceProperty.Attributes |= MemberAttributes.Static; CodePropertyReferenceExpression resMgrPropertyReferenceExpression = new CodePropertyReferenceExpression(null, ResMgrPropertyName); CodeFieldReferenceExpression cultureInfoFieldReference = new CodeFieldReferenceExpression(useStatic ? null : ((CodeExpression) new CodeThisReferenceExpression()), CultureInfoFieldName); bool stringResourceDataType = typeof(string) == resourceDataType; bool memoryStreamResourceDataType = (typeof(UnmanagedMemoryStream) == resourceDataType) || (typeof(MemoryStream) == resourceDataType); string methodName = "GetObject"; string codeCommentString = string.Format(CultureInfo.CurrentCulture, NonStringPropertyComment, resourceName); if (stringResourceDataType) { methodName = "GetString"; string resourceStringValue = resourceData.ValueIfString; if (resourceStringValue.Length > DocCommentLengthThreshold) { resourceStringValue = string.Format(CultureInfo.CurrentCulture, StringTruncatedComment, resourceStringValue.Substring(0, DocCommentLengthThreshold)); } resourceStringValue = SecurityElement.Escape(resourceStringValue); codeCommentString = string.Format(CultureInfo.CurrentCulture, StringPropertyComment, resourceStringValue); } else if (memoryStreamResourceDataType) methodName = "GetStream"; AddComments(resourceProperty, codeCommentString); CodeExpression invokeCodeExpression = new CodeMethodInvokeExpression(resMgrPropertyReferenceExpression, methodName, new CodeExpression[] { new CodePrimitiveExpression(resourceName), cultureInfoFieldReference }); if (stringResourceDataType || memoryStreamResourceDataType) propertyReturnStatement = new CodeMethodReturnStatement(invokeCodeExpression); else propertyReturnStatement = new CodeMethodReturnStatement(new CodeCastExpression(resourceDataTypeReference, invokeCodeExpression)); resourceProperty.GetStatements.Add(propertyReturnStatement); resourceClass.Members.Add(resourceProperty); return true; }
/// <summary>Generates a class file that contains strongly-typed properties that match the resources in the specified .resx file.</summary> /// <returns>A <see cref="T:System.CodeDom.CodeCompileUnit"></see> container.</returns> /// <param name="callerType">The type of the caller class.</param> /// <param name="baseName">The name of the class to be generated.</param> /// <param name="internalClass">true to generate an internal class; false to generate a public class.</param> /// <param name="resourcesNamespace">The namespace of the resource to be generated. </param> /// <param name="codeProvider">A <see cref="T:System.CodeDom.Compiler.CodeDomProvider"></see> class that provides the language in which the class will be generated. When langauge is Visual Basic (<see cref="System.CodeDom.Compiler.CodeDomProvider.FileExtension"/> is vb (case insensitive)) modle is generated instead of class.</param> /// <param name="unmatchable">A list that contains each resource name for which a property cannot be generated. Typically, a property cannot be generated because the resource name is not a valid identifier.</param> /// <param name="generatedCodeNamespace">The namespace of the class to be generated.</param> /// <param name="resxFile">The name of a .resx file used as input.</param> /// <exception cref="T:System.ArgumentNullException">basename or codeProvider is null.</exception> /// <param name="logicalName">Name of resource stream in assembly</param> /// <version version="1.5.3">Since version 1.5.3 modules are generated for Visual Basic.</version> public static CodeCompileUnit Create(Type callerType, string resxFile, string baseName, string generatedCodeNamespace, string resourcesNamespace, CodeDomProvider codeProvider, bool internalClass, List<ResourceErrorData> unmatchable, string logicalName) { //logicalName added by Ðonny if (null == resxFile) throw new ArgumentNullException("resxFile"); Dictionary<string, ResourceData> resourceDataDictionary = new Dictionary<string, ResourceData>(StringComparer.InvariantCultureIgnoreCase); using (ResXResourceReader resXReader = new ResXResourceReader(resxFile)) { resXReader.UseResXDataNodes = true; foreach (DictionaryEntry resourceEntry in resXReader) { ResXDataNode resXNode = (ResXDataNode)resourceEntry.Value; string valueTypeName = resXNode.GetValueTypeName((AssemblyName[]) null); Type valueType = Type.GetType(valueTypeName); string valueText = null; if (valueType == typeof(string)) valueText = (string)resXNode.GetValue((AssemblyName[]) null); ResourceData resourceData = new ResourceData(valueType, valueText); resourceDataDictionary.Add((string) resourceEntry.Key, resourceData); } } return InternalCreate(callerType, resourceDataDictionary, baseName, generatedCodeNamespace, resourcesNamespace, codeProvider, internalClass, unmatchable, logicalName); }
private static void DefineFormattedResourceFetchingMethod(string methodName, string propertyName, string resourceName, ResourceData resourceData, CodeTypeDeclaration resourceClass, bool internalClass, bool useStatic, int numberOfArguments) { Type stringType = resourceData.Type; Type objectType = typeof(object); CodeMethodReturnStatement methodReturnStatement; CodeMemberMethod resourceFormatMethod = new CodeMemberMethod(); resourceFormatMethod.Name = methodName; for (int index = 0; index < numberOfArguments; ++index) { CodeParameterDeclarationExpression parameterDeclarationExpression = new CodeParameterDeclarationExpression(objectType, "arg" + index.ToString(CultureInfo.InvariantCulture)); resourceFormatMethod.Parameters.Add(parameterDeclarationExpression); } // Prevent the code analysis error indicating to use a param array if (numberOfArguments > 3) { CodeAttributeDeclaration suppressAttributeDeclaration = new CodeAttributeDeclaration(new CodeTypeReference(typeof(SuppressMessageAttribute))); suppressAttributeDeclaration.AttributeType.Options = CodeTypeReferenceOptions.GlobalReference; suppressAttributeDeclaration.Arguments.Add(new CodeAttributeArgument(new CodePrimitiveExpression("Microsoft.Design"))); suppressAttributeDeclaration.Arguments.Add(new CodeAttributeArgument(new CodePrimitiveExpression("CA1025:ReplaceRepetitiveArgumentsWithParamsArray"))); resourceFormatMethod.CustomAttributes.Add(suppressAttributeDeclaration); } CodeTypeReference stringTypeReference = new CodeTypeReference(stringType); resourceFormatMethod.ReturnType = stringTypeReference; /*if (internalClass) resourceFormatMethod.Attributes = MemberAttributes.Assembly; else*///Ð resourceFormatMethod.Attributes = MemberAttributes.Public; if (useStatic) resourceFormatMethod.Attributes |= MemberAttributes.Static; string resourceStringValue = resourceData.ValueIfString; if (resourceStringValue.Length > DocCommentLengthThreshold) { resourceStringValue = string.Format(CultureInfo.CurrentCulture, StringTruncatedComment, resourceStringValue.Substring(0, DocCommentLengthThreshold)); } resourceStringValue = SecurityElement.Escape(resourceStringValue); string codeCommentString = numberOfArguments > 0 ? string.Format(CultureInfo.CurrentCulture, FormatMethodComment, resourceStringValue) : string.Format(CultureInfo.CurrentCulture, FormatStubMethodComment, propertyName); AddComments(resourceFormatMethod, codeCommentString); for (int index = 0; index < numberOfArguments; ++index) { resourceFormatMethod.Comments.Add(new CodeCommentStatement(string.Format(CultureInfo.InvariantCulture, ParamCommentStatement, index), true)); } string returnValueCommentString = numberOfArguments > 0 ? MethodReturnValueComment : string.Format(StubMethodReturnValueComment, propertyName); resourceFormatMethod.Comments.Add(new CodeCommentStatement(returnValueCommentString, true)); CodePropertyReferenceExpression resPropertyReferenceExpression = new CodePropertyReferenceExpression(null, propertyName); if (numberOfArguments > 0) { CodeFieldReferenceExpression cultureInfoFieldReference = new CodeFieldReferenceExpression(useStatic ? null : ((CodeExpression)new CodeThisReferenceExpression()), CultureInfoFieldName); CodeTypeReferenceExpression stringTypeReferenceExpression = new CodeTypeReferenceExpression(stringTypeReference); CodeMethodReferenceExpression stringFormatMethodReference = new CodeMethodReferenceExpression(stringTypeReferenceExpression, "Format"); CodeExpression[] formatExpressionParameters = new CodeExpression[2 + numberOfArguments]; formatExpressionParameters[0] = cultureInfoFieldReference; formatExpressionParameters[1] = resPropertyReferenceExpression; for (int index = 0; index < numberOfArguments; ++index) { CodeVariableReferenceExpression parameterReference = new CodeVariableReferenceExpression("arg" + index.ToString(CultureInfo.InvariantCulture)); formatExpressionParameters[2 + index] = parameterReference; } CodeExpression stringFormatExpression = new CodeMethodInvokeExpression(stringFormatMethodReference, formatExpressionParameters); methodReturnStatement = new CodeMethodReturnStatement(stringFormatExpression); } else methodReturnStatement = new CodeMethodReturnStatement(resPropertyReferenceExpression); resourceFormatMethod.Statements.Add(methodReturnStatement); resourceClass.Members.Add(resourceFormatMethod); }
/// <summary>Generates a class file that contains strongly-typed properties that match the resources referenced in the specified collection.</summary> /// <returns>A <see cref="T:System.CodeDom.CodeCompileUnit"></see> container.</returns> /// <param name="callerType">The type of the caller class.</param> /// <param name="baseName">The name of the class to be generated.</param> /// <param name="internalClass">true to generate an internal class; false to generate a public class.</param> /// <param name="resourcesNamespace">The namespace of the resource to be generated. </param> /// <param name="generatedCodeNamespace">The namespace of the class to be generated.</param> /// <param name="codeProvider">A <see cref="T:System.CodeDom.Compiler.CodeDomProvider"></see> object that provides the language in which the class will be generated. When langauge is Visual Basic (<see cref="System.CodeDom.Compiler.CodeDomProvider.FileExtension"/> is vb (case insensitive)) modle is generated instead of class.</param> /// <param name="resourceList">An <see cref="T:System.Collections.IDictionary"></see> collection where each dictionary entry key/value pair is the name of a resource and the value of the resource.</param> /// <param name="unmatchable">A list that contains each resource name for which a property cannot be generated. Typically, a property cannot be generated because the resource name is not a valid identifier.</param> /// <exception cref="T:System.ArgumentNullException">resourceList, basename, or codeProvider is null.</exception> /// <version version="1.5.3">Since version 1.5.3 modules are generated for Visual Basic.</version> public static CodeCompileUnit Create(Type callerType, IDictionary resourceList, string baseName, string generatedCodeNamespace, string resourcesNamespace, CodeDomProvider codeProvider, bool internalClass, List<ResourceErrorData> unmatchable,string logicalName) { //logicalName added by Ðonny if (null == resourceList) throw new ArgumentNullException("resourceList"); Dictionary<string, ResourceData> resourceDataDictionary = new Dictionary<string, ResourceData>(StringComparer.InvariantCultureIgnoreCase); foreach (DictionaryEntry resourceEntry in resourceList) { ResourceData resourceData; ResXDataNode resXNode = resourceEntry.Value as ResXDataNode; if (null != resXNode) { string resourceKey = (string)resourceEntry.Key; if (resourceKey != resXNode.Name) throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, MismatchedResourceName, resourceKey, resXNode.Name)); string valueTypeName = resXNode.GetValueTypeName((AssemblyName[]) null); Type valueType = Type.GetType(valueTypeName); string valueText = null; if (valueType == typeof(string)) valueText = (string) resXNode.GetValue((AssemblyName[]) null); resourceData = new ResourceData(valueType, valueText); } else { Type valueType = (null == resourceEntry.Value) ? typeof(object) : resourceEntry.Value.GetType(); resourceData = new ResourceData(valueType, resourceEntry.Value as string); } resourceDataDictionary.Add((string) resourceEntry.Key, resourceData); } return InternalCreate(callerType, resourceDataDictionary, baseName, generatedCodeNamespace, resourcesNamespace, codeProvider, internalClass, unmatchable, logicalName); //logicalName added by Ðonny }