From 9c1fa71138e7712dd1e8fb6efc0ba3f5f4a22007 Mon Sep 17 00:00:00 2001 From: Trent Dixon Date: Mon, 12 Sep 2022 16:09:00 +1000 Subject: [PATCH 1/7] Fixes spaces in member names in generated C# --- .../Templates/ODataT4CodeGenerator.cs | 56 ++++++++++--------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/src/Unchase.OData.ConnectedService.Shared/Templates/ODataT4CodeGenerator.cs b/src/Unchase.OData.ConnectedService.Shared/Templates/ODataT4CodeGenerator.cs index 43b07f4..435af38 100644 --- a/src/Unchase.OData.ConnectedService.Shared/Templates/ODataT4CodeGenerator.cs +++ b/src/Unchase.OData.ConnectedService.Shared/Templates/ODataT4CodeGenerator.cs @@ -2534,7 +2534,7 @@ internal void WritePropertiesForStructuredType(IEnumerable propert foreach (var propertyInfo in propertyInfos) { - string privatePropertyName = uniqueIdentifierService.GetUniqueIdentifier("_" + propertyInfo.PropertyName); + string privatePropertyName = uniqueIdentifierService.GetUniqueIdentifier("_" + propertyInfo.FixedPropertyName); this.WritePropertyForStructuredType( propertyInfo.PropertyType, @@ -2567,7 +2567,7 @@ internal void WriteMembersForEnumType(IEnumerable members) } } - internal string GetFixedName(string originalName) + internal virtual string GetFixedName(string originalName) { string fixedName = originalName; @@ -2830,17 +2830,9 @@ public string ToStringWithCulture(object objectToConvert) throw new global::System.ArgumentNullException("objectToConvert"); } System.Type t = objectToConvert.GetType(); - System.Reflection.MethodInfo method = t.GetMethod("ToString", new System.Type[] { - typeof(System.IFormatProvider)}); - if ((method == null)) - { - return objectToConvert.ToString(); - } - else - { - return ((string)(method.Invoke(objectToConvert, new object[] { - this.formatProviderField }))); - } + System.Reflection.MethodInfo method = t.GetMethod("ToString", new System.Type[] { typeof(System.IFormatProvider)}); + + return ((method == null ? objectToConvert.ToString() : ((string)(method.Invoke(objectToConvert, new object[] { this.formatProviderField })))) ?? String.Empty); } } private ToStringInstanceHelper toStringHelperField = new ToStringInstanceHelper(); @@ -3489,6 +3481,18 @@ public ODataClientCSharpTemplate(CodeGenerationContext context) internal override string ParameterDeclarationTemplate => "{0} {1}"; internal override string DictionaryItemConstructor => "{{ {0}, {1} }}"; + internal override string GetFixedName(string originalName) + { + string fixedName = originalName; + + if (this.LanguageKeywords.Contains(fixedName)) + { + fixedName = string.Format(this.FixPattern, fixedName); + } + + return (fixedName ?? String.Empty).Replace(' ', '_'); + } + internal override HashSet LanguageKeywords { get { if (CSharpKeywords == null) { @@ -3538,7 +3542,7 @@ internal override void WriteNamespaceStart(string fullNamespace) this.Write("namespace "); -this.Write(this.ToStringHelper.ToStringWithCulture(fullNamespace)); +this.Write(this.ToStringHelper.ToStringWithCulture(this.GetFixedName(fullNamespace))); this.Write("\r\n{\r\n"); @@ -3860,11 +3864,11 @@ internal override void WriteContextEntitySetProperty(string entitySetName, strin this.Write(" if ((this._"); -this.Write(this.ToStringHelper.ToStringWithCulture(entitySetName)); +this.Write(this.ToStringHelper.ToStringWithCulture(entitySetFixedName)); this.Write(" == null))\r\n {\r\n this._"); -this.Write(this.ToStringHelper.ToStringWithCulture(entitySetName)); +this.Write(this.ToStringHelper.ToStringWithCulture(entitySetFixedName)); this.Write(" = "); @@ -3880,7 +3884,7 @@ internal override void WriteContextEntitySetProperty(string entitySetName, strin this.Write(");\r\n }\r\n return this._"); -this.Write(this.ToStringHelper.ToStringWithCulture(entitySetName)); +this.Write(this.ToStringHelper.ToStringWithCulture(entitySetFixedName)); this.Write(";\r\n }\r\n }\r\n [global::System.CodeDom.Compiler.GeneratedCo" + "deAttribute(\"Microsoft.OData.Client.Design.T4\", \""); @@ -3893,7 +3897,7 @@ internal override void WriteContextEntitySetProperty(string entitySetName, strin this.Write("> _"); -this.Write(this.ToStringHelper.ToStringWithCulture(entitySetName)); +this.Write(this.ToStringHelper.ToStringWithCulture(entitySetFixedName)); this.Write(";\r\n"); @@ -3950,11 +3954,11 @@ internal override void WriteContextSingletonProperty(string singletonName, strin this.Write(" if ((this._"); -this.Write(this.ToStringHelper.ToStringWithCulture(singletonName)); +this.Write(this.ToStringHelper.ToStringWithCulture(singletonFixedName)); this.Write(" == null))\r\n {\r\n this._"); -this.Write(this.ToStringHelper.ToStringWithCulture(singletonName)); +this.Write(this.ToStringHelper.ToStringWithCulture(singletonFixedName)); this.Write(" = new "); @@ -3970,7 +3974,7 @@ internal override void WriteContextSingletonProperty(string singletonName, strin this.Write(");\r\n }\r\n return this._"); -this.Write(this.ToStringHelper.ToStringWithCulture(singletonName)); +this.Write(this.ToStringHelper.ToStringWithCulture(singletonFixedName)); this.Write(";\r\n }\r\n }\r\n [global::System.CodeDom.Compiler.GeneratedCo" + "deAttribute(\"Microsoft.OData.Client.Design.T4\", \""); @@ -3983,7 +3987,7 @@ internal override void WriteContextSingletonProperty(string singletonName, strin this.Write(" _"); -this.Write(this.ToStringHelper.ToStringWithCulture(singletonName)); +this.Write(this.ToStringHelper.ToStringWithCulture(singletonFixedName)); this.Write(";\r\n"); @@ -4558,7 +4562,7 @@ internal override void WritePropertyForStructuredType(string propertyType, strin this.Write(";\r\n }\r\n set\r\n {\r\n this.On"); -this.Write(this.ToStringHelper.ToStringWithCulture(propertyName)); +this.Write(this.ToStringHelper.ToStringWithCulture(fixedPropertyName)); this.Write("Changing(value);\r\n this."); @@ -4566,7 +4570,7 @@ internal override void WritePropertyForStructuredType(string propertyType, strin this.Write(" = value;\r\n this.On"); -this.Write(this.ToStringHelper.ToStringWithCulture(propertyName)); +this.Write(this.ToStringHelper.ToStringWithCulture(fixedPropertyName)); this.Write("Changed();\r\n"); @@ -4600,7 +4604,7 @@ internal override void WritePropertyForStructuredType(string propertyType, strin this.Write(";\r\n partial void On"); -this.Write(this.ToStringHelper.ToStringWithCulture(propertyName)); +this.Write(this.ToStringHelper.ToStringWithCulture(fixedPropertyName)); this.Write("Changing("); @@ -4608,7 +4612,7 @@ internal override void WritePropertyForStructuredType(string propertyType, strin this.Write(" value);\r\n partial void On"); -this.Write(this.ToStringHelper.ToStringWithCulture(propertyName)); +this.Write(this.ToStringHelper.ToStringWithCulture(fixedPropertyName)); this.Write("Changed();\r\n"); From d8deb6461ab33c6cdca7dfddc8554bcc4623468c Mon Sep 17 00:00:00 2001 From: Trent Dixon Date: Tue, 13 Sep 2022 12:31:57 +1000 Subject: [PATCH 2/7] Add pattern fixing to .ttinclude --- .../Templates/ODataT4CodeGenerator.cs | 6 +++--- .../Templates/ODataT4CodeGenerator.ttinclude | 15 ++++++++++++++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/Unchase.OData.ConnectedService.Shared/Templates/ODataT4CodeGenerator.cs b/src/Unchase.OData.ConnectedService.Shared/Templates/ODataT4CodeGenerator.cs index 435af38..d0a71b2 100644 --- a/src/Unchase.OData.ConnectedService.Shared/Templates/ODataT4CodeGenerator.cs +++ b/src/Unchase.OData.ConnectedService.Shared/Templates/ODataT4CodeGenerator.cs @@ -49,7 +49,7 @@ The above copyright notice and this permission notice shall be included in all c THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - + try { CodeGenerationContext context; @@ -1812,7 +1812,7 @@ internal void WriteEntityContainer(IEdmEntityContainer container, string fullNam if (this.context.EnableNamingAlias) { camelCaseEntitySetName = Customization.CustomizeNaming(camelCaseEntitySetName); - } + } this.WriteContextAddToEntitySetMethod(camelCaseEntitySetName, entitySet.Name, GetFixedName(entitySetElementTypeName), parameterName); } @@ -1834,7 +1834,7 @@ internal void WriteEntityContainer(IEdmEntityContainer container, string fullNam edmNavigationSourceList.Add(singleton); } } - + this.WriteGeneratedEdmModel(Utils.SerializeToString(this.context.Edmx).Replace("\"", "\"\"")); bool hasOperationImport = container.OperationImports().OfType().Any(); diff --git a/src/Unchase.OData.ConnectedService.Shared/Templates/ODataT4CodeGenerator.ttinclude b/src/Unchase.OData.ConnectedService.Shared/Templates/ODataT4CodeGenerator.ttinclude index d3fda9e..e220a98 100644 --- a/src/Unchase.OData.ConnectedService.Shared/Templates/ODataT4CodeGenerator.ttinclude +++ b/src/Unchase.OData.ConnectedService.Shared/Templates/ODataT4CodeGenerator.ttinclude @@ -2497,7 +2497,7 @@ public abstract class ODataClientTemplate : TemplateBase } } - internal string GetFixedName(string originalName) + internal virtual string GetFixedName(string originalName) { string fixedName = originalName; @@ -3442,6 +3442,19 @@ public sealed class ODataClientCSharpTemplate : ODataClientTemplate internal override string ODataVersion { get { return "global::Microsoft.OData.ODataVersion.V4"; } } internal override string ParameterDeclarationTemplate { get { return "{0} {1}"; } } internal override string DictionaryItemConstructor { get { return "{{ {0}, {1} }}"; } } + + internal override string GetFixedName(string originalName) + { + string fixedName = originalName; + + if (this.LanguageKeywords.Contains(fixedName)) + { + fixedName = string.Format(this.FixPattern, fixedName); + } + + return (fixedName ?? String.Empty).Replace(' ', '_'); + } + internal override HashSet LanguageKeywords { get { if (CSharpKeywords == null) { From b58f69bcdd4ef452614f4d16133d42c4fb189f65 Mon Sep 17 00:00:00 2001 From: Trent Dixon Date: Wed, 14 Sep 2022 14:26:52 +1000 Subject: [PATCH 3/7] Add option to load Edmx from resource instead of string literal --- .../CodeGeneration/V4CodeGenDescriptor.cs | 19 ++++ .../Common/Constants.cs | 2 + .../Models/ServiceConfiguration.cs | 2 + .../Models/UserSettings.cs | 3 + .../Templates/ODataT4CodeGenerator.cs | 105 ++++++++++++++---- .../ViewModels/AdvancedSettingsViewModel.cs | 21 ++++ .../Views/AdvancedSettings.xaml | 15 ++- .../Views/ConfigODataEndpoint.xaml.cs | 1 + .../Wizard.cs | 7 ++ 9 files changed, 153 insertions(+), 22 deletions(-) diff --git a/src/Unchase.OData.ConnectedService.Shared/CodeGeneration/V4CodeGenDescriptor.cs b/src/Unchase.OData.ConnectedService.Shared/CodeGeneration/V4CodeGenDescriptor.cs index 9cbe3d0..2b1342b 100644 --- a/src/Unchase.OData.ConnectedService.Shared/CodeGeneration/V4CodeGenDescriptor.cs +++ b/src/Unchase.OData.ConnectedService.Shared/CodeGeneration/V4CodeGenDescriptor.cs @@ -42,6 +42,15 @@ public override async Task AddNugetPackagesAsync() await CheckAndInstallNuGetPackageAsync(Common.Constants.NuGetOnlineRepository, nugetPackage); await this.Context.Logger.WriteMessageAsync(LoggerMessageCategory.Information, "Nuget Packages for OData V4 were installed."); + + if (this.ServiceConfiguration.EmbedEdmxFile) + { + await this.Context.Logger.WriteMessageAsync(LoggerMessageCategory.Information, "Adding Nuget Packages for embedded Edmx resource..."); + + await CheckAndInstallNuGetPackageAsync(Common.Constants.NuGetOnlineRepository, Common.Constants.MSEmbeddedResourcePackage); + + await this.Context.Logger.WriteMessageAsync(LoggerMessageCategory.Information, "Nuget Packages for embedded Edmx resource were installed."); + } } internal async Task CheckAndInstallNuGetPackageAsync(string packageSource, string nugetPackage) @@ -148,6 +157,7 @@ private async Task AddGeneratedCodeAsync() IgnoreUnexpectedElementsAndAttributes = this.ServiceConfiguration.IgnoreUnexpectedElementsAndAttributes, EnableNamingAlias = this.ServiceConfiguration.EnableNamingAlias, NamespacePrefix = this.ServiceConfiguration.NamespacePrefix, + EmbedEdmxFilePath = this.ServiceConfiguration.EmbedEdmxFile ? Path.Combine(this.Context.HandlerHelper.GetServiceArtifactsRootFolder(), this.Context.ServiceInstance.Name, $"{this.GeneratedFileNamePrefix}.edmx").Replace('\\', '.').Replace(' ', '_') : null, ExcludedOperationImportsNames = this.ServiceConfiguration?.ExcludedOperationImportsNames, GenerateDynamicPropertiesCollection = this.ServiceConfiguration.GenerateDynamicPropertiesCollection, DynamicPropertiesCollectionName = this.ServiceConfiguration?.DynamicPropertiesCollectionName, @@ -171,6 +181,15 @@ private async Task AddGeneratedCodeAsync() var outputFile = Path.Combine(this.ReferenceFileFolder, $"{this.GeneratedFileNamePrefix}{(this.ServiceConfiguration.LanguageOption == LanguageOption.GenerateCSharpCode ? ".cs" : ".vb")}"); await this.Context.HandlerHelper.AddFileAsync(tempFile, outputFile, new AddFileOptions { OpenOnComplete = this.Instance.ServiceConfig.OpenGeneratedFilesOnComplete }); + if (this.ServiceConfiguration.EmbedEdmxFile) + { + var projFilePath = Path.Combine(this.ReferenceFileFolder, $"{this.GeneratedFileNamePrefix}.edmx"); + File.WriteAllText(projFilePath, t4CodeGenerator.Edmx); + + var item = this.Project.ProjectItems.AddFromFile(projFilePath); + item.Properties.Item("ItemType").Value = "EmbeddedResource"; + } + await this.Context.Logger.WriteMessageAsync(LoggerMessageCategory.Information, "Client Proxy for OData V4 was generated."); } diff --git a/src/Unchase.OData.ConnectedService.Shared/Common/Constants.cs b/src/Unchase.OData.ConnectedService.Shared/Common/Constants.cs index 5f66afa..f5f95dc 100644 --- a/src/Unchase.OData.ConnectedService.Shared/Common/Constants.cs +++ b/src/Unchase.OData.ConnectedService.Shared/Common/Constants.cs @@ -43,6 +43,8 @@ internal static class Constants public const string V4EdmNuGetPackage = "Microsoft.OData.Edm"; public const string V4SpatialNuGetPackage = "Microsoft.Spatial"; + public const string MSEmbeddedResourcePackage = "Microsoft.Extensions.FileProviders.Embedded"; + public const string EdmxVersion1Namespace = "http://schemas.microsoft.com/ado/2007/06/edmx"; public const string EdmxVersion2Namespace = "http://schemas.microsoft.com/ado/2008/10/edmx"; public const string EdmxVersion3Namespace = "http://schemas.microsoft.com/ado/2009/11/edmx"; diff --git a/src/Unchase.OData.ConnectedService.Shared/Models/ServiceConfiguration.cs b/src/Unchase.OData.ConnectedService.Shared/Models/ServiceConfiguration.cs index 4002ab0..ac033fd 100644 --- a/src/Unchase.OData.ConnectedService.Shared/Models/ServiceConfiguration.cs +++ b/src/Unchase.OData.ConnectedService.Shared/Models/ServiceConfiguration.cs @@ -90,6 +90,8 @@ internal class ServiceConfigurationV4 : ServiceConfigurationV3 public bool IncludeT4File { get; set; } + public bool EmbedEdmxFile { get; set; } + public bool MakeTypesInternal { get; set; } } diff --git a/src/Unchase.OData.ConnectedService.Shared/Models/UserSettings.cs b/src/Unchase.OData.ConnectedService.Shared/Models/UserSettings.cs index 8ab93f5..a9c4f1a 100644 --- a/src/Unchase.OData.ConnectedService.Shared/Models/UserSettings.cs +++ b/src/Unchase.OData.ConnectedService.Shared/Models/UserSettings.cs @@ -78,6 +78,9 @@ internal class UserSettings [DataMember] public bool IncludeT4File { get; set; } + [DataMember] + public bool EmbedEdmxFile { get; set; } + [DataMember] public bool MakeTypesInternal { get; set; } diff --git a/src/Unchase.OData.ConnectedService.Shared/Templates/ODataT4CodeGenerator.cs b/src/Unchase.OData.ConnectedService.Shared/Templates/ODataT4CodeGenerator.cs index d0a71b2..b74405f 100644 --- a/src/Unchase.OData.ConnectedService.Shared/Templates/ODataT4CodeGenerator.cs +++ b/src/Unchase.OData.ConnectedService.Shared/Templates/ODataT4CodeGenerator.cs @@ -61,6 +61,7 @@ The above copyright notice and this permission notice shall be included in all c UseAsyncDataServiceCollection = this.UseAsyncDataServiceCollection, TargetLanguage = this.TargetLanguage, EnableNamingAlias = this.EnableNamingAlias, + EmbedEdmxFilePath = this.EmbedEdmxFilePath, TempFilePath = this.TempFilePath, IgnoreUnexpectedElementsAndAttributes = this.IgnoreUnexpectedElementsAndAttributes, GenerateDynamicPropertiesCollection = this.GenerateDynamicPropertiesCollection, @@ -83,6 +84,7 @@ The above copyright notice and this permission notice shall be included in all c UseAsyncDataServiceCollection = this.UseAsyncDataServiceCollection, TargetLanguage = this.TargetLanguage, EnableNamingAlias = this.EnableNamingAlias, + EmbedEdmxFilePath = this.EmbedEdmxFilePath, TempFilePath = this.TempFilePath, IgnoreUnexpectedElementsAndAttributes = this.IgnoreUnexpectedElementsAndAttributes, GenerateDynamicPropertiesCollection = this.GenerateDynamicPropertiesCollection, @@ -90,6 +92,8 @@ The above copyright notice and this permission notice shall be included in all c ExcludedOperationImportsNames = this.ExcludedOperationImportsNames, MakeTypesInternal = this.MakeTypesInternal }; + + this.Edmx = Utils.SerializeToString(context.Edmx); } if (this.GetReferencedModelReaderFunc != null) @@ -340,6 +344,15 @@ public bool EnableNamingAlias set; } +/// +/// true to embed the Edmx as a file, false to include it as a string literal +/// +public string EmbedEdmxFilePath +{ + get; + set; +} + /// /// The path for the temporary file where the metadata xml document can be stored. /// @@ -988,6 +1001,15 @@ public bool EnableNamingAlias set; } + /// + /// pass an action that takes an edmx string and a filename to embed edmx as a file, otherwise null + /// + public string EmbedEdmxFilePath + { + get; + set; + } + /// /// true to ignore unknown elements or attributes in metadata, false otherwise. /// @@ -1834,7 +1856,7 @@ internal void WriteEntityContainer(IEdmEntityContainer container, string fullNam edmNavigationSourceList.Add(singleton); } } - + this.WriteGeneratedEdmModel(Utils.SerializeToString(this.context.Edmx).Replace("\"", "\"\"")); bool hasOperationImport = container.OperationImports().OfType().Any(); @@ -3467,7 +3489,7 @@ public ODataClientCSharpTemplate(CodeGenerationContext context) internal override string XmlConvertClassName => "global::System.Xml.XmlConvert"; internal override string EnumTypeName => "global::System.Enum"; internal override string DictionaryTypeName => "global::System.Collections.Generic.Dictionary<{0}, {1}>"; - internal override string FixPattern => "@{0}"; + internal override string FixPattern => "_{0}"; internal override string EnumUnderlyingTypeMarker => " : "; internal override string ConstantExpressionConstructorWithType => "global::System.Linq.Expressions.Expression.Constant({0}, typeof({1}))"; internal override string TypeofFormatter => "typeof({0})"; @@ -3504,7 +3526,8 @@ internal override HashSet LanguageKeywords { get { "long", "namespace", "new", "null", "object", "operator", "out", "override", "params", "private", "protected", "public", "readonly", "ref", "return", "sbyte", "sealed", "string", "short", "sizeof", "stackalloc", "static", "struct", "switch", "this", "throw", "true", "try", "typeof", "uint", "ulong", "unchecked", "unsafe", "ushort", "using", "virtual", "volatile", - "void", "while" + "void", "while", + "Context" // Not actually a keyword, but a necessary inherited property }; } return CSharpKeywords; @@ -4045,6 +4068,7 @@ internal override void WriteGeneratedEdmModel(string escapedEdmxString) } bool useTempFile = !String.IsNullOrEmpty(path) && System.IO.File.Exists(path); + bool useEmbeddedFile = !String.IsNullOrEmpty(this.context.EmbedEdmxFilePath); this.Write(" [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"Microsoft.OData." + "Client.Design.T4\", \""); @@ -4097,8 +4121,23 @@ internal override void WriteGeneratedEdmModel(string escapedEdmxString) " = LoadModelFromString();\r\n"); - if (useTempFile) + if (useEmbeddedFile) { +this.Write(" [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"Microsoft.OD" + + "ata.Client.Design.T4\", \""); + +this.Write(this.ToStringHelper.ToStringWithCulture(T4Version)); + +this.Write("\")]\r\n private const string EmbeddedEdmxPath = @\""); + +this.Write(this.ToStringHelper.ToStringWithCulture(this.context.EmbedEdmxFilePath)); + +this.Write("\";\r\n"); + } + else + { + if (useTempFile) + { this.Write(" \r\n [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"Microsof" + "t.OData.Client.Design.T4\", \""); @@ -4112,9 +4151,9 @@ internal override void WriteGeneratedEdmModel(string escapedEdmxString) this.Write("\";\r\n"); - } - else - { + } + else + { this.Write(" [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"Microsoft.OD" + "ata.Client.Design.T4\", \""); @@ -4128,6 +4167,7 @@ internal override void WriteGeneratedEdmModel(string escapedEdmxString) this.Write("\";\r\n"); + } } this.Write(" [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"Microsoft.OD" + @@ -4166,7 +4206,11 @@ internal override void WriteGeneratedEdmModel(string escapedEdmxString) "omString()\r\n {\r\n"); - if (useTempFile) + if (useEmbeddedFile) + { +this.Write(" global::System.Xml.XmlReader reader = CreateXmlReader(EmbeddedEdmxPath);\r\n"); + } + else if (useTempFile) { this.Write(" \r\n global::System.Xml.XmlReader reader = CreateXmlReader();\r\n"); @@ -4206,7 +4250,11 @@ internal override void WriteGeneratedEdmModel(string escapedEdmxString) "omString()\r\n {\r\n"); - if (useTempFile) + if (useEmbeddedFile) + { +this.Write(" global::System.Xml.XmlReader reader = CreateXmlReader(EmbeddedEdmxPath);\r\n"); + } + else if (useTempFile) { this.Write(" \r\n global::System.Xml.XmlReader reader = CreateXmlReader();\r\n"); @@ -4253,17 +4301,21 @@ internal override void WriteGeneratedEdmModel(string escapedEdmxString) } -this.Write(" [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"Microsoft.OD" + - "ata.Client.Design.T4\", \""); - -this.Write(this.ToStringHelper.ToStringWithCulture(T4Version)); - -this.Write("\")]\r\n private static global::System.Xml.XmlReader CreateXmlReader(stri" + - "ng edmxToParse)\r\n {\r\n return global::System.Xml.XmlRea" + - "der.Create(new global::System.IO.StringReader(edmxToParse));\r\n }\r\n"); + if (useEmbeddedFile) + { + this.Write(" [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"Microsoft.OData.Client.Design.T4\", \""); + this.Write(this.ToStringHelper.ToStringWithCulture(T4Version)); - if (useTempFile) + this.Write(@""")] + private static global::System.Xml.XmlReader CreateXmlReader(string edmxEmbedPath) + { + var embeddedProvider = new Microsoft.Extensions.FileProviders.EmbeddedFileProvider(System.Reflection.Assembly.GetExecutingAssembly()); + return global::System.Xml.XmlReader.Create(new global::System.IO.StreamReader(embeddedProvider.GetFileInfo(edmxEmbedPath).CreateReadStream())); + } +"); + } + else if (useTempFile) { this.Write(" \r\n [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"Mic" + @@ -4276,9 +4328,21 @@ internal override void WriteGeneratedEdmModel(string escapedEdmxString) "eate(new global::System.IO.StreamReader(filePath));\r\n }\r\n"); + } + else + { +this.Write(" [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"Microsoft.OD" + + "ata.Client.Design.T4\", \""); + +this.Write(this.ToStringHelper.ToStringWithCulture(T4Version)); + +this.Write("\")]\r\n private static global::System.Xml.XmlReader CreateXmlReader(stri" + + "ng edmxToParse)\r\n {\r\n return global::System.Xml.XmlRea" + + "der.Create(new global::System.IO.StringReader(edmxToParse));\r\n }\r\n"); + } -this.Write(" }\r\n"); + this.Write(" }\r\n"); } @@ -5656,7 +5720,8 @@ internal override HashSet LanguageKeywords { get { "Select", "Set", "Shadows", "Shared", "Short", "Single", "Static", "Step", "Stop", "String", "Structure", "Sub", "SyncLock", "Then", "Throw", "To", "True", "Try", "TryCast", "TypeOf", "UInteger", "ULong", "UShort", "Using", "Variant", "Wend", "When", "While", "Widening", "With", - "WithEvents", "WriteOnly", "Xor" + "WithEvents", "WriteOnly", "Xor", + "Context" // Not actually a keyword, but a necessary inherited property }; } return VBKeywords; diff --git a/src/Unchase.OData.ConnectedService.Shared/ViewModels/AdvancedSettingsViewModel.cs b/src/Unchase.OData.ConnectedService.Shared/ViewModels/AdvancedSettingsViewModel.cs index d89cd88..d49113a 100644 --- a/src/Unchase.OData.ConnectedService.Shared/ViewModels/AdvancedSettingsViewModel.cs +++ b/src/Unchase.OData.ConnectedService.Shared/ViewModels/AdvancedSettingsViewModel.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using System.Windows; using Microsoft.VisualStudio.ConnectedServices; +using Microsoft.VisualStudio.Debugger.Interop; using Unchase.OData.ConnectedService.Common; using Unchase.OData.ConnectedService.Models; using Unchase.OData.ConnectedService.Views; @@ -183,6 +184,24 @@ public bool IncludeT4File } #endregion + #region EmbedEdmxFileEnabled + public bool EmbedEdmxFileEnabled { get; set; } + #endregion + + #region EmbedEdmxFile + private bool _embedEdmxFile; + public bool EmbedEdmxFile + { + get => _embedEdmxFile; + set + { + _embedEdmxFile = value; + UserSettings.EmbedEdmxFile = value; + OnPropertyChanged(nameof(EmbedEdmxFile)); + } + } + #endregion + #region MakeTypesInternal private bool _makeTypesInternal; public bool MakeTypesInternal @@ -291,6 +310,8 @@ public override async Task OnPageEnteringAsync(WizardEnteringArgs args) this.GeneratedFileNamePrefix = UserSettings.GeneratedFileNamePrefix ?? Constants.DefaultReferenceFileName; this.IncludeT4FileEnabled = true; this.IncludeT4File = UserSettings.IncludeT4File; + this.EmbedEdmxFileEnabled = true; + this.EmbedEdmxFile = UserSettings.EmbedEdmxFile; this.MakeTypesInternal = UserSettings.MakeTypesInternal; this.IncludeExtensionsT4File = UserSettings.IncludeExtensionsT4File; this.OperationImportsGenerator = UserSettings.OperationImportsGenerator; diff --git a/src/Unchase.OData.ConnectedService.Shared/Views/AdvancedSettings.xaml b/src/Unchase.OData.ConnectedService.Shared/Views/AdvancedSettings.xaml index 182549d..177cfed 100644 --- a/src/Unchase.OData.ConnectedService.Shared/Views/AdvancedSettings.xaml +++ b/src/Unchase.OData.ConnectedService.Shared/Views/AdvancedSettings.xaml @@ -9,7 +9,7 @@ d:DesignHeight="460" d:DesignWidth="500" mc:Ignorable="d"> - + + + Date: Wed, 14 Sep 2022 14:45:35 +1000 Subject: [PATCH 4/7] Adds scrolling to advanced options --- .../Views/AdvancedSettings.xaml | 96 ++++++++++--------- 1 file changed, 49 insertions(+), 47 deletions(-) diff --git a/src/Unchase.OData.ConnectedService.Shared/Views/AdvancedSettings.xaml b/src/Unchase.OData.ConnectedService.Shared/Views/AdvancedSettings.xaml index 177cfed..ad39c95 100644 --- a/src/Unchase.OData.ConnectedService.Shared/Views/AdvancedSettings.xaml +++ b/src/Unchase.OData.ConnectedService.Shared/Views/AdvancedSettings.xaml @@ -9,19 +9,20 @@ d:DesignHeight="460" d:DesignWidth="500" mc:Ignorable="d"> - - + + - - - You can generate the client proxy based on the default settings, or you can click following link for further configuration. - - + AdvancedSettings - - - - + + + - - + Use a custom namespace (It will replace the original namespace in the metadata document, unless the model has several namespaces). - - - + + - - + - - - - + - - + - - + - - - + - + - - - - - Ignore unknown elements (Whether to ignore unexpected elements and attributes in the metadata document and generate the client code if any). - - Ignore unknown elements (Whether to ignore unexpected elements and attributes in the metadata document and generate the client code if any). + + - Make generated types internal (Enable this if you don't want to expose the generated types outside of your assembly). - + Make generated types internal (Enable this if you don't want to expose the generated types outside of your assembly). + - - Generate Dynamic Properties Collection with name : - - Generate Dynamic Properties Collection with name : + + - - - + OperationImports (ActionImports and FunctionImports) names in metadata to exclude from generated code (comma separated): - - + + - + From 7a0ff06b78016385a7287a49ae45514901a56802 Mon Sep 17 00:00:00 2001 From: Trent Dixon Date: Thu, 15 Sep 2022 10:10:40 +1000 Subject: [PATCH 5/7] Fixes AppVeyor build error re ambiguous reference --- .../ViewModels/AdvancedSettingsViewModel.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Unchase.OData.ConnectedService.Shared/ViewModels/AdvancedSettingsViewModel.cs b/src/Unchase.OData.ConnectedService.Shared/ViewModels/AdvancedSettingsViewModel.cs index d49113a..ca65914 100644 --- a/src/Unchase.OData.ConnectedService.Shared/ViewModels/AdvancedSettingsViewModel.cs +++ b/src/Unchase.OData.ConnectedService.Shared/ViewModels/AdvancedSettingsViewModel.cs @@ -7,7 +7,7 @@ using System.Windows; using Microsoft.VisualStudio.ConnectedServices; using Microsoft.VisualStudio.Debugger.Interop; -using Unchase.OData.ConnectedService.Common; +using Common = Unchase.OData.ConnectedService.Common; using Unchase.OData.ConnectedService.Models; using Unchase.OData.ConnectedService.Views; @@ -16,8 +16,8 @@ namespace Unchase.OData.ConnectedService.ViewModels internal class AdvancedSettingsViewModel : ConnectedServiceWizardPage { #region Properties and fields - public Constants.OperationImportsGenerator[] OperationImportsGenerators => - new[] { Constants.OperationImportsGenerator.Inner, Constants.OperationImportsGenerator.SimpleOData}; + public Common.Constants.OperationImportsGenerator[] OperationImportsGenerators => + new[] { Common.Constants.OperationImportsGenerator.Inner, Common.Constants.OperationImportsGenerator.SimpleOData}; #region UseDataServiceCollection private bool _useDataServiceCollection; @@ -231,8 +231,8 @@ public bool IncludeExtensionsT4File #endregion #region OperationImportsGenerator - private Constants.OperationImportsGenerator _operationImportsGenerator; - public Constants.OperationImportsGenerator OperationImportsGenerator + private Common.Constants.OperationImportsGenerator _operationImportsGenerator; + public Common.Constants.OperationImportsGenerator OperationImportsGenerator { get => _operationImportsGenerator; set @@ -301,13 +301,13 @@ public override async Task OnPageEnteringAsync(WizardEnteringArgs args) this.UseDataServiceCollection = UserSettings.UseDataServiceCollection; this.UseAsyncDataServiceCollection = UserSettings.UseAsyncDataServiceCollection; this.UseNamespacePrefix = UserSettings.UseNameSpacePrefix; - this.NamespacePrefix = UserSettings.NamespacePrefix ?? Constants.DefaultNamespacePrefix; + this.NamespacePrefix = UserSettings.NamespacePrefix ?? Common.Constants.DefaultNamespacePrefix; this.EnableNamingAlias = UserSettings.EnableNamingAlias; this.IgnoreUnexpectedElementsAndAttributes = UserSettings.IgnoreUnexpectedElementsAndAttributes; this.GenerateDynamicPropertiesCollection = UserSettings.GenerateDynamicPropertiesCollection; this.DynamicPropertiesCollectionName = UserSettings.DynamicPropertiesCollectionName; this.GeneratedFileNameEnabled = true; - this.GeneratedFileNamePrefix = UserSettings.GeneratedFileNamePrefix ?? Constants.DefaultReferenceFileName; + this.GeneratedFileNamePrefix = UserSettings.GeneratedFileNamePrefix ?? Common.Constants.DefaultReferenceFileName; this.IncludeT4FileEnabled = true; this.IncludeT4File = UserSettings.IncludeT4File; this.EmbedEdmxFileEnabled = true; From 8174ce9eea85b8e1425f4422a2e12fddb2f16672 Mon Sep 17 00:00:00 2001 From: Trent Dixon Date: Thu, 15 Sep 2022 12:07:36 +1000 Subject: [PATCH 6/7] Better fix for #86 Added new GetFixedNamePart that just does the whitespace replacement, using this for private members --- .../Templates/ODataT4CodeGenerator.cs | 113 +++++++++--------- 1 file changed, 59 insertions(+), 54 deletions(-) diff --git a/src/Unchase.OData.ConnectedService.Shared/Templates/ODataT4CodeGenerator.cs b/src/Unchase.OData.ConnectedService.Shared/Templates/ODataT4CodeGenerator.cs index b74405f..3d94d3c 100644 --- a/src/Unchase.OData.ConnectedService.Shared/Templates/ODataT4CodeGenerator.cs +++ b/src/Unchase.OData.ConnectedService.Shared/Templates/ODataT4CodeGenerator.cs @@ -1365,8 +1365,8 @@ public ODataClientTemplate(CodeGenerationContext context) internal abstract void WriteMethodStartForResolveNameFromType(string containerName, string fullNamespace); internal abstract void WriteResolveType(string fullNamespace, string languageDependentNamespace); internal abstract void WriteMethodEndForResolveNameFromType(bool modelHasInheritance); - internal abstract void WriteContextEntitySetProperty(string entitySetName, string entitySetFixedName, string originalEntitySetName, string entitySetElementTypeName, bool inContext = true); - internal abstract void WriteContextSingletonProperty(string singletonName, string singletonFixedName, string originalSingletonName, string singletonElementTypeName, bool inContext = true); + internal abstract void WriteContextEntitySetProperty(string entitySetName, string entitySetFixedName, string entitySetPrivateName, string originalEntitySetName, string entitySetElementTypeName, bool inContext = true); + internal abstract void WriteContextSingletonProperty(string singletonName, string singletonFixedName, string singletonPrivateName, string originalSingletonName, string singletonElementTypeName, bool inContext = true); internal abstract void WriteContextAddToEntitySetMethod(string entitySetName, string originalEntitySetName, string typeName, string parameterName); internal abstract void WriteGeneratedEdmModel(string escapedEdmxString); internal abstract void WriteClassEndForEntityContainer(); @@ -1811,7 +1811,7 @@ internal void WriteEntityContainer(IEdmEntityContainer container, string fullNam camelCaseEntitySetName = Customization.CustomizeNaming(camelCaseEntitySetName); } - this.WriteContextEntitySetProperty(camelCaseEntitySetName, GetFixedName(camelCaseEntitySetName), entitySet.Name, GetFixedName(entitySetElementTypeName)); + this.WriteContextEntitySetProperty(GetFixedNamePart(camelCaseEntitySetName), GetFixedName(camelCaseEntitySetName), GetFixedNamePart($"_{camelCaseEntitySetName}"), entitySet.Name, GetFixedName(entitySetElementTypeName)); if (!this.context.ElementTypeToNavigationSourceMap.TryGetValue(entitySet.EntityType(), out var edmNavigationSourceList)) { edmNavigationSourceList = new List(); @@ -1836,7 +1836,7 @@ internal void WriteEntityContainer(IEdmEntityContainer container, string fullNam camelCaseEntitySetName = Customization.CustomizeNaming(camelCaseEntitySetName); } - this.WriteContextAddToEntitySetMethod(camelCaseEntitySetName, entitySet.Name, GetFixedName(entitySetElementTypeName), parameterName); + this.WriteContextAddToEntitySetMethod(GetFixedNamePart(camelCaseEntitySetName), entitySet.Name, GetFixedName(entitySetElementTypeName), parameterName); } foreach (IEdmSingleton singleton in container.Singletons()) @@ -1849,7 +1849,7 @@ internal void WriteEntityContainer(IEdmEntityContainer container, string fullNam camelCaseSingletonName = Customization.CustomizeNaming(camelCaseSingletonName); } - this.WriteContextSingletonProperty(camelCaseSingletonName, GetFixedName(camelCaseSingletonName), singleton.Name, singletonElementTypeName + "Single"); + this.WriteContextSingletonProperty(GetFixedNamePart(camelCaseSingletonName), GetFixedName(camelCaseSingletonName), GetFixedNamePart($"_{camelCaseSingletonName}"), singleton.Name, singletonElementTypeName + "Single"); if (this.context.ElementTypeToNavigationSourceMap.TryGetValue(singleton.EntityType(), out var edmNavigationSourceList)) { @@ -2002,12 +2002,12 @@ internal void WritePropertiesForSingleType(IEnumerable properties) if (property.Type is Microsoft.OData.Edm.EdmCollectionTypeReference) { propertyType = GetSourceOrReturnTypeName(property.Type); - WriteContextEntitySetProperty(propertyName, GetFixedName(propertyName), property.Name, propertyType, false); + WriteContextEntitySetProperty(GetFixedNamePart(propertyName), GetFixedName(propertyName), GetFixedNamePart($"_{propertyName}"), property.Name, propertyType, false); } else { propertyType = Utils.GetClrTypeName(property.Type, true, this, this.context, true, isEntitySingleType : true); - WriteContextSingletonProperty(propertyName, GetFixedName(propertyName), property.Name, propertyType, false); + WriteContextSingletonProperty(GetFixedNamePart(propertyName), GetFixedName(propertyName), GetFixedNamePart($"_{propertyName}"), property.Name, propertyType, false); } } } @@ -2530,9 +2530,9 @@ internal void WritePropertiesForStructuredType(IEnumerable propert { PropertyType = Utils.GetClrTypeName(property.Type, useDataServiceCollection, this, this.context), PropertyVanillaName = property.Name, - PropertyName = propertyName, + PropertyName = GetFixedNamePart(propertyName), FixedPropertyName = GetFixedName(propertyName), - PrivatePropertyName = "_" + propertyName, + PrivatePropertyName = GetFixedNamePart(Utils.CamelCase($"_{propertyName}")), PropertyInitializationValue = Utils.GetPropertyInitializationValue(property, useDataServiceCollection, this, this.context) }; }).ToList(); @@ -2543,9 +2543,9 @@ internal void WritePropertiesForStructuredType(IEnumerable propert { PropertyType = string.Format(this.DictionaryTypeName, this.StringTypeName, this.ObjectTypeName), PropertyVanillaName = string.Empty, // No such property in metadata - PropertyName = this.context.DynamicPropertiesCollectionName, + PropertyName = GetFixedNamePart(this.context.DynamicPropertiesCollectionName), FixedPropertyName = GetFixedName(this.context.DynamicPropertiesCollectionName), - PrivatePropertyName = "_" + Utils.CamelCase(this.context.DynamicPropertiesCollectionName), + PrivatePropertyName = GetFixedNamePart(Utils.CamelCase($"_{this.context.DynamicPropertiesCollectionName}")), PropertyInitializationValue = string.Format(this.DictionaryConstructor, this.StringTypeName, this.ObjectTypeName) }); } @@ -2556,7 +2556,7 @@ internal void WritePropertiesForStructuredType(IEnumerable propert foreach (var propertyInfo in propertyInfos) { - string privatePropertyName = uniqueIdentifierService.GetUniqueIdentifier("_" + propertyInfo.FixedPropertyName); + string privatePropertyName = uniqueIdentifierService.GetUniqueIdentifier(propertyInfo.PrivatePropertyName); this.WritePropertyForStructuredType( propertyInfo.PropertyType, @@ -2601,6 +2601,11 @@ internal virtual string GetFixedName(string originalName) return fixedName; } + internal string GetFixedNamePart(string originalNamePart) + { + return originalNamePart.Replace(' ', '_'); + } + internal string GetElementTypeName(IEdmEntityType elementType, IEdmEntityContainer container) { string elementTypeName = elementType.Name; @@ -3489,7 +3494,7 @@ public ODataClientCSharpTemplate(CodeGenerationContext context) internal override string XmlConvertClassName => "global::System.Xml.XmlConvert"; internal override string EnumTypeName => "global::System.Enum"; internal override string DictionaryTypeName => "global::System.Collections.Generic.Dictionary<{0}, {1}>"; - internal override string FixPattern => "_{0}"; + internal override string FixPattern => "@{0}"; internal override string EnumUnderlyingTypeMarker => " : "; internal override string ConstantExpressionConstructorWithType => "global::System.Linq.Expressions.Expression.Constant({0}, typeof({1}))"; internal override string TypeofFormatter => "typeof({0})"; @@ -3512,7 +3517,7 @@ internal override string GetFixedName(string originalName) fixedName = string.Format(this.FixPattern, fixedName); } - return (fixedName ?? String.Empty).Replace(' ', '_'); + return GetFixedNamePart(fixedName ?? String.Empty); } internal override HashSet LanguageKeywords { get { @@ -3837,7 +3842,7 @@ internal override void WriteConstructorForSingleType(string singleTypeName, stri } - internal override void WriteContextEntitySetProperty(string entitySetName, string entitySetFixedName, string originalEntitySetName, string entitySetElementTypeName, bool inContext) + internal override void WriteContextEntitySetProperty(string entitySetName, string entitySetFixedName, string entitySetPrivateName, string originalEntitySetName, string entitySetElementTypeName, bool inContext) { this.Write(" /// \r\n /// There are no comments for "); @@ -3885,13 +3890,13 @@ internal override void WriteContextEntitySetProperty(string entitySetName, strin } -this.Write(" if ((this._"); +this.Write(" if ((this."); -this.Write(this.ToStringHelper.ToStringWithCulture(entitySetFixedName)); +this.Write(this.ToStringHelper.ToStringWithCulture(entitySetPrivateName)); -this.Write(" == null))\r\n {\r\n this._"); +this.Write(" == null))\r\n {\r\n this."); -this.Write(this.ToStringHelper.ToStringWithCulture(entitySetFixedName)); +this.Write(this.ToStringHelper.ToStringWithCulture(entitySetPrivateName)); this.Write(" = "); @@ -3905,9 +3910,9 @@ internal override void WriteContextEntitySetProperty(string entitySetName, strin this.Write(this.ToStringHelper.ToStringWithCulture(inContext ? "\"" + originalEntitySetName + "\"" : "GetPath(\"" + originalEntitySetName + "\")")); -this.Write(");\r\n }\r\n return this._"); +this.Write(");\r\n }\r\n return this."); -this.Write(this.ToStringHelper.ToStringWithCulture(entitySetFixedName)); +this.Write(this.ToStringHelper.ToStringWithCulture(entitySetPrivateName)); this.Write(";\r\n }\r\n }\r\n [global::System.CodeDom.Compiler.GeneratedCo" + "deAttribute(\"Microsoft.OData.Client.Design.T4\", \""); @@ -3918,16 +3923,16 @@ internal override void WriteContextEntitySetProperty(string entitySetName, strin this.Write(this.ToStringHelper.ToStringWithCulture(entitySetElementTypeName)); -this.Write("> _"); +this.Write("> "); -this.Write(this.ToStringHelper.ToStringWithCulture(entitySetFixedName)); +this.Write(this.ToStringHelper.ToStringWithCulture(entitySetPrivateName)); this.Write(";\r\n"); } - internal override void WriteContextSingletonProperty(string singletonName, string singletonFixedName, string originalSingletonName, string singletonElementTypeName, bool inContext) + internal override void WriteContextSingletonProperty(string singletonName, string singletonFixedName, string singletonPrivateName, string originalSingletonName, string singletonElementTypeName, bool inContext) { this.Write(" /// \r\n /// There are no comments for "); @@ -3975,13 +3980,13 @@ internal override void WriteContextSingletonProperty(string singletonName, strin } -this.Write(" if ((this._"); +this.Write(" if ((this."); -this.Write(this.ToStringHelper.ToStringWithCulture(singletonFixedName)); +this.Write(this.ToStringHelper.ToStringWithCulture(singletonPrivateName)); -this.Write(" == null))\r\n {\r\n this._"); +this.Write(" == null))\r\n {\r\n this."); -this.Write(this.ToStringHelper.ToStringWithCulture(singletonFixedName)); +this.Write(this.ToStringHelper.ToStringWithCulture(singletonPrivateName)); this.Write(" = new "); @@ -3995,9 +4000,9 @@ internal override void WriteContextSingletonProperty(string singletonName, strin this.Write(this.ToStringHelper.ToStringWithCulture(inContext ? "\"" + originalSingletonName + "\"" : "GetPath(\"" + originalSingletonName + "\")")); -this.Write(");\r\n }\r\n return this._"); +this.Write(");\r\n }\r\n return this."); -this.Write(this.ToStringHelper.ToStringWithCulture(singletonFixedName)); +this.Write(this.ToStringHelper.ToStringWithCulture(singletonPrivateName)); this.Write(";\r\n }\r\n }\r\n [global::System.CodeDom.Compiler.GeneratedCo" + "deAttribute(\"Microsoft.OData.Client.Design.T4\", \""); @@ -4008,9 +4013,9 @@ internal override void WriteContextSingletonProperty(string singletonName, strin this.Write(this.ToStringHelper.ToStringWithCulture(singletonElementTypeName)); -this.Write(" _"); +this.Write(" "); -this.Write(this.ToStringHelper.ToStringWithCulture(singletonFixedName)); +this.Write(this.ToStringHelper.ToStringWithCulture(singletonPrivateName)); this.Write(";\r\n"); @@ -4626,7 +4631,7 @@ internal override void WritePropertyForStructuredType(string propertyType, strin this.Write(";\r\n }\r\n set\r\n {\r\n this.On"); -this.Write(this.ToStringHelper.ToStringWithCulture(fixedPropertyName)); +this.Write(this.ToStringHelper.ToStringWithCulture(propertyName)); this.Write("Changing(value);\r\n this."); @@ -4634,7 +4639,7 @@ internal override void WritePropertyForStructuredType(string propertyType, strin this.Write(" = value;\r\n this.On"); -this.Write(this.ToStringHelper.ToStringWithCulture(fixedPropertyName)); +this.Write(this.ToStringHelper.ToStringWithCulture(propertyName)); this.Write("Changed();\r\n"); @@ -4668,7 +4673,7 @@ internal override void WritePropertyForStructuredType(string propertyType, strin this.Write(";\r\n partial void On"); -this.Write(this.ToStringHelper.ToStringWithCulture(fixedPropertyName)); +this.Write(this.ToStringHelper.ToStringWithCulture(propertyName)); this.Write("Changing("); @@ -4676,7 +4681,7 @@ internal override void WritePropertyForStructuredType(string propertyType, strin this.Write(" value);\r\n partial void On"); -this.Write(this.ToStringHelper.ToStringWithCulture(fixedPropertyName)); +this.Write(this.ToStringHelper.ToStringWithCulture(propertyName)); this.Write("Changed();\r\n"); @@ -6072,7 +6077,7 @@ End Sub } - internal override void WriteContextEntitySetProperty(string entitySetName, string entitySetFixedName, string originalEntitySetName, string entitySetElementTypeName, bool inContext) + internal override void WriteContextEntitySetProperty(string entitySetName, string entitySetFixedName, string entitySetPrivateName, string originalEntitySetName, string entitySetElementTypeName, bool inContext) { this.Write(" \'\'\'\r\n \'\'\'There are no comments for "); @@ -6120,13 +6125,13 @@ internal override void WriteContextEntitySetProperty(string entitySetName, strin } -this.Write(" If (Me._"); +this.Write(" If (Me."); -this.Write(this.ToStringHelper.ToStringWithCulture(entitySetName)); +this.Write(this.ToStringHelper.ToStringWithCulture(entitySetPrivateName)); -this.Write(" Is Nothing) Then\r\n Me._"); +this.Write(" Is Nothing) Then\r\n Me."); -this.Write(this.ToStringHelper.ToStringWithCulture(entitySetName)); +this.Write(this.ToStringHelper.ToStringWithCulture(entitySetPrivateName)); this.Write(" = "); @@ -6140,18 +6145,18 @@ internal override void WriteContextEntitySetProperty(string entitySetName, strin this.Write(this.ToStringHelper.ToStringWithCulture(inContext ? "\"" + originalEntitySetName + "\"" : "GetPath(\"" + originalEntitySetName + "\")")); -this.Write(")\r\n End If\r\n Return Me._"); +this.Write(")\r\n End If\r\n Return Me."); -this.Write(this.ToStringHelper.ToStringWithCulture(entitySetName)); +this.Write(this.ToStringHelper.ToStringWithCulture(entitySetPrivateName)); this.Write("\r\n End Get\r\n End Property\r\n _\r\n Private _"); +this.Write("\")> _\r\n Private "); -this.Write(this.ToStringHelper.ToStringWithCulture(entitySetName)); +this.Write(this.ToStringHelper.ToStringWithCulture(entitySetPrivateName)); this.Write(" As Global.Microsoft.OData.Client.DataServiceQuery(Of "); @@ -6162,7 +6167,7 @@ internal override void WriteContextEntitySetProperty(string entitySetName, strin } - internal override void WriteContextSingletonProperty(string singletonName, string singletonFixedName, string originalSingletonName, string singletonElementTypeName, bool inContext) + internal override void WriteContextSingletonProperty(string singletonName, string singletonFixedName, string singletonPrivateName, string originalSingletonName, string singletonElementTypeName, bool inContext) { this.Write(" \'\'\'\r\n \'\'\'There are no comments for "); @@ -6210,13 +6215,13 @@ internal override void WriteContextSingletonProperty(string singletonName, strin } -this.Write(" If (Me._"); +this.Write(" If (Me."); -this.Write(this.ToStringHelper.ToStringWithCulture(singletonName)); +this.Write(this.ToStringHelper.ToStringWithCulture(singletonPrivateName)); -this.Write(" Is Nothing) Then\r\n Me._"); +this.Write(" Is Nothing) Then\r\n Me."); -this.Write(this.ToStringHelper.ToStringWithCulture(singletonName)); +this.Write(this.ToStringHelper.ToStringWithCulture(singletonPrivateName)); this.Write(" = New "); @@ -6230,18 +6235,18 @@ internal override void WriteContextSingletonProperty(string singletonName, strin this.Write(this.ToStringHelper.ToStringWithCulture(inContext ? "\"" + originalSingletonName + "\"" : "GetPath(\"" + originalSingletonName + "\")")); -this.Write(")\r\n End If\r\n Return Me._"); +this.Write(")\r\n End If\r\n Return Me."); -this.Write(this.ToStringHelper.ToStringWithCulture(singletonName)); +this.Write(this.ToStringHelper.ToStringWithCulture(singletonPrivateName)); this.Write("\r\n End Get\r\n End Property\r\n _\r\n Private _"); +this.Write("\")> _\r\n Private "); -this.Write(this.ToStringHelper.ToStringWithCulture(singletonName)); +this.Write(this.ToStringHelper.ToStringWithCulture(singletonPrivateName)); this.Write(" As "); From b93901c08550f30c3ab80bacb1a07a6222fe1922 Mon Sep 17 00:00:00 2001 From: Trent Dixon Date: Thu, 15 Sep 2022 13:36:57 +1000 Subject: [PATCH 7/7] Separate fix for inherited members and language keywords --- .../Templates/ODataT4CodeGenerator.cs | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/Unchase.OData.ConnectedService.Shared/Templates/ODataT4CodeGenerator.cs b/src/Unchase.OData.ConnectedService.Shared/Templates/ODataT4CodeGenerator.cs index 3d94d3c..a0e52b1 100644 --- a/src/Unchase.OData.ConnectedService.Shared/Templates/ODataT4CodeGenerator.cs +++ b/src/Unchase.OData.ConnectedService.Shared/Templates/ODataT4CodeGenerator.cs @@ -1142,7 +1142,7 @@ public string GetPrefixedNamespace(string ns, ODataClientTemplate template, bool { if (template.LanguageKeywords.Contains(segments[i])) { - prefixedNamespace += string.Format(CultureInfo.InvariantCulture, template.FixPattern, segments[i]); + prefixedNamespace += string.Format(CultureInfo.InvariantCulture, template.FixKeywordPattern, segments[i]); } else { @@ -1335,7 +1335,12 @@ public ODataClientTemplate(CodeGenerationContext context) internal abstract string EnumTypeName { get; } internal abstract string DictionaryTypeName { get; } internal abstract HashSet LanguageKeywords { get; } - internal abstract string FixPattern { get; } + internal HashSet ReservedMemberNames = new HashSet(StringComparer.Ordinal) + { + "Context" + }; + internal abstract string FixKeywordPattern { get; } + internal string FixReservedMemberNamePattern = "{0}_"; internal abstract string EnumUnderlyingTypeMarker { get; } internal abstract string ConstantExpressionConstructorWithType { get; } internal abstract string TypeofFormatter { get; } @@ -2595,7 +2600,7 @@ internal virtual string GetFixedName(string originalName) if (this.LanguageKeywords.Contains(fixedName)) { - fixedName = string.Format(this.FixPattern, fixedName); + fixedName = string.Format(this.FixKeywordPattern, fixedName); } return fixedName; @@ -3494,7 +3499,7 @@ public ODataClientCSharpTemplate(CodeGenerationContext context) internal override string XmlConvertClassName => "global::System.Xml.XmlConvert"; internal override string EnumTypeName => "global::System.Enum"; internal override string DictionaryTypeName => "global::System.Collections.Generic.Dictionary<{0}, {1}>"; - internal override string FixPattern => "@{0}"; + internal override string FixKeywordPattern => "@{0}"; internal override string EnumUnderlyingTypeMarker => " : "; internal override string ConstantExpressionConstructorWithType => "global::System.Linq.Expressions.Expression.Constant({0}, typeof({1}))"; internal override string TypeofFormatter => "typeof({0})"; @@ -3512,9 +3517,13 @@ internal override string GetFixedName(string originalName) { string fixedName = originalName; + if (this.ReservedMemberNames.Contains(fixedName)) + { + fixedName = string.Format(this.FixReservedMemberNamePattern, fixedName); + } if (this.LanguageKeywords.Contains(fixedName)) { - fixedName = string.Format(this.FixPattern, fixedName); + fixedName = string.Format(this.FixKeywordPattern, fixedName); } return GetFixedNamePart(fixedName ?? String.Empty); @@ -3531,8 +3540,7 @@ internal override HashSet LanguageKeywords { get { "long", "namespace", "new", "null", "object", "operator", "out", "override", "params", "private", "protected", "public", "readonly", "ref", "return", "sbyte", "sealed", "string", "short", "sizeof", "stackalloc", "static", "struct", "switch", "this", "throw", "true", "try", "typeof", "uint", "ulong", "unchecked", "unsafe", "ushort", "using", "virtual", "volatile", - "void", "while", - "Context" // Not actually a keyword, but a necessary inherited property + "void", "while" }; } return CSharpKeywords; @@ -5692,7 +5700,7 @@ public ODataClientVBTemplate(CodeGenerationContext context) internal override string XmlConvertClassName { get { return "Global.System.Xml.XmlConvert"; } } internal override string EnumTypeName { get { return "Global.System.Enum"; } } internal override string DictionaryTypeName { get { return "Global.System.Collections.Generic.Dictionary(Of {0}, {1})"; } } - internal override string FixPattern { get { return "[{0}]"; } } + internal override string FixKeywordPattern { get { return "[{0}]"; } } internal override string EnumUnderlyingTypeMarker { get { return " As "; } } internal override string ConstantExpressionConstructorWithType { get { return "Global.System.Linq.Expressions.Expression.Constant({0}, GetType({1}))"; } } internal override string TypeofFormatter { get { return "GetType({0})"; } } @@ -5725,8 +5733,7 @@ internal override HashSet LanguageKeywords { get { "Select", "Set", "Shadows", "Shared", "Short", "Single", "Static", "Step", "Stop", "String", "Structure", "Sub", "SyncLock", "Then", "Throw", "To", "True", "Try", "TryCast", "TypeOf", "UInteger", "ULong", "UShort", "Using", "Variant", "Wend", "When", "While", "Widening", "With", - "WithEvents", "WriteOnly", "Xor", - "Context" // Not actually a keyword, but a necessary inherited property + "WithEvents", "WriteOnly", "Xor" }; } return VBKeywords;