Skip to content

Properly handle type definitions elements in schema #103

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 24 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
90ba262
Make generated c# class and methods internal
habbes Jan 16, 2020
642304e
Remove internal modifier from generated methods and properties
habbes Jan 16, 2020
e1ee353
Use class access modifier on VB enums and extension classes
habbes Jan 16, 2020
cabbdde
Add UI option to enable generating types as internal
habbes Jan 17, 2020
baf0ffa
Add ODataConnectedService support for VS 2019
habbes Jan 17, 2020
589caf1
Re-enable signing
habbes Jan 17, 2020
691c839
Fix inconsistent indentation
habbes Jan 17, 2020
244cc87
Create test solution for ODataConnectedService
habbes Jan 21, 2020
5d35c27
Add tests for V4CodeGenDescriptor
habbes Jan 22, 2020
92673ae
Refactor V4CodeGenDescriptor
habbes Jan 22, 2020
dce321d
Add tests for ODataConnectedServiceHander
habbes Jan 22, 2020
444ff8d
Refactor ODataConnectedService tests
habbes Jan 23, 2020
7373a5a
Rename ODataConnectedService validators arguments
habbes Jan 23, 2020
6c3097c
Hide option to make types internal if generating code for odata v3 or…
habbes Jan 23, 2020
b67bdd9
Update code generator
habbes Jan 23, 2020
9da3292
Fix indentation issues in code generator template
habbes Jan 23, 2020
e72c731
Rename test namespace
habbes Jan 23, 2020
81d69ca
Add license header to new source files
habbes Jan 23, 2020
c896e6c
Add note on unit tests to README
habbes Jan 23, 2020
be346c6
Re-enable signing
habbes Jan 23, 2020
3dd1260
Fix indentation issue
habbes Jan 23, 2020
a056fef
Properly handle TypeDefinition schema elements during code generation
habbes Jan 28, 2020
ef54f9e
Test support for nullable TypeDefinitions
habbes Jan 28, 2020
5449bdb
Refactor GetClrTypeName in code generator
habbes Jan 28, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions ODataConnectedService/ODataConnectedService.Tests.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29613.14
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ODataConnectedService", "src\ODataConnectedService.csproj", "{A8BC5B8E-9AB7-4257-B8F1-E7C62169F9B5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ODataConnectedService.Tests", "test\ODataConnectedService.Tests\ODataConnectedService.Tests.csproj", "{903B31D0-BE14-4D9E-BA76-186FA82B3A37}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A8BC5B8E-9AB7-4257-B8F1-E7C62169F9B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A8BC5B8E-9AB7-4257-B8F1-E7C62169F9B5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A8BC5B8E-9AB7-4257-B8F1-E7C62169F9B5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A8BC5B8E-9AB7-4257-B8F1-E7C62169F9B5}.Release|Any CPU.Build.0 = Release|Any CPU
{903B31D0-BE14-4D9E-BA76-186FA82B3A37}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{903B31D0-BE14-4D9E-BA76-186FA82B3A37}.Debug|Any CPU.Build.0 = Debug|Any CPU
{903B31D0-BE14-4D9E-BA76-186FA82B3A37}.Release|Any CPU.ActiveCfg = Release|Any CPU
{903B31D0-BE14-4D9E-BA76-186FA82B3A37}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {FD696714-8F52-4A00-93F4-43C843F184DB}
EndGlobalSection
EndGlobal
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public BaseCodeGenDescriptor(string metadataUri, ConnectedServiceHandlerContext
this.ServiceConfiguration = ((ODataConnectedServiceInstance)this.Context.ServiceInstance).ServiceConfig;
}

private void Init()
protected virtual void Init()
{
var componentModel = (IComponentModel)Shell.Package.GetGlobalService(typeof(SComponentModel));
this.PackageInstallerServices = componentModel.GetService<IVsPackageInstallerServices>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
using System.Globalization;
using EnvDTE;
using Microsoft.VisualStudio.ConnectedServices;
using Microsoft.OData.ConnectedService.Templates;

namespace Microsoft.OData.ConnectedService.CodeGeneration
{
class CodeGenDescriptorFactory: ICodeGenDescriptorFactory
{
public BaseCodeGenDescriptor Create(Version edmxVersion, string metadataUri, ConnectedServiceHandlerContext context, Project project)
{
if (edmxVersion == Common.Constants.EdmxVersion1
|| edmxVersion == Common.Constants.EdmxVersion2
|| edmxVersion == Common.Constants.EdmxVersion3)
{
return CreateV3CodeGenDescriptor(metadataUri, context, project);
}
else if (edmxVersion == Common.Constants.EdmxVersion4)
{
return CreateV4CodeGenDescriptor(metadataUri, context, project);
}
throw new Exception(string.Format(CultureInfo.InvariantCulture, "Not supported Edmx Version {0}", edmxVersion.ToString()));
}

protected virtual BaseCodeGenDescriptor CreateV3CodeGenDescriptor(string metadataUri, ConnectedServiceHandlerContext context, Project project)
{
return new V3CodeGenDescriptor(metadataUri, context, project);
}

protected virtual BaseCodeGenDescriptor CreateV4CodeGenDescriptor(string metadataUri, ConnectedServiceHandlerContext context, Project project)
{
return new V4CodeGenDescriptor(metadataUri, context, project, new ODataT4CodeGeneratorFactory());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
using EnvDTE;
using Microsoft.VisualStudio.ConnectedServices;

namespace Microsoft.OData.ConnectedService.CodeGeneration
{
interface ICodeGenDescriptorFactory
{
BaseCodeGenDescriptor Create(Version edmxVersion, string metadataUri, ConnectedServiceHandlerContext context, Project project);
}
}
16 changes: 10 additions & 6 deletions ODataConnectedService/src/CodeGeneration/V4CodeGenDescriptor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,17 @@ namespace Microsoft.OData.ConnectedService.CodeGeneration
{
internal class V4CodeGenDescriptor : BaseCodeGenDescriptor
{
public V4CodeGenDescriptor(string metadataUri, ConnectedServiceHandlerContext context, Project project)
public V4CodeGenDescriptor(string metadataUri, ConnectedServiceHandlerContext context, Project project, IODataT4CodeGeneratorFactory codeGeneratorFactory)
: base(metadataUri, context, project)
{
this.ClientNuGetPackageName = Common.Constants.V4ClientNuGetPackage;
this.ClientDocUri = Common.Constants.V4DocUri;
this.ServiceConfiguration = base.ServiceConfiguration as ServiceConfigurationV4;
ClientNuGetPackageName = Common.Constants.V4ClientNuGetPackage;
ClientDocUri = Common.Constants.V4DocUri;
ServiceConfiguration = base.ServiceConfiguration as ServiceConfigurationV4;
CodeGeneratorFactory = codeGeneratorFactory;
}

private IODataT4CodeGeneratorFactory CodeGeneratorFactory { get; set; }

private new ServiceConfigurationV4 ServiceConfiguration { get; set; }

public override async Task AddNugetPackages()
Expand Down Expand Up @@ -66,7 +69,7 @@ private async Task AddT4File()
text = Regex.Replace(text, "(public const string TargetLanguage = )\"OutputLanguage\";", "$1\"CSharp\";");
text = Regex.Replace(text, "(public const bool EnableNamingAlias = )true;", "$1" + this.ServiceConfiguration.EnableNamingAlias.ToString().ToLower(CultureInfo.InvariantCulture) + ";");
text = Regex.Replace(text, "(public const bool IgnoreUnexpectedElementsAndAttributes = )true;", "$1" + this.ServiceConfiguration.IgnoreUnexpectedElementsAndAttributes.ToString().ToLower(CultureInfo.InvariantCulture) + ";");

text = Regex.Replace(text, "(public const bool MakeTypesInternal = )false;", "$1" + ServiceConfiguration.MakeTypesInternal.ToString().ToLower(CultureInfo.InvariantCulture) + ";");
await writer.WriteAsync(text);
await writer.FlushAsync();
}
Expand All @@ -78,13 +81,14 @@ private async Task AddT4File()

private async Task AddGeneratedCSharpCode()
{
ODataT4CodeGenerator t4CodeGenerator = new ODataT4CodeGenerator();
ODataT4CodeGenerator t4CodeGenerator = CodeGeneratorFactory.Create();
t4CodeGenerator.MetadataDocumentUri = MetadataUri;
t4CodeGenerator.UseDataServiceCollection = this.ServiceConfiguration.UseDataServiceCollection;
t4CodeGenerator.TargetLanguage = ODataT4CodeGenerator.LanguageOption.CSharp;
t4CodeGenerator.IgnoreUnexpectedElementsAndAttributes = this.ServiceConfiguration.IgnoreUnexpectedElementsAndAttributes;
t4CodeGenerator.EnableNamingAlias = this.ServiceConfiguration.EnableNamingAlias;
t4CodeGenerator.NamespacePrefix = this.ServiceConfiguration.NamespacePrefix;
t4CodeGenerator.MakeTypesInternal = ServiceConfiguration.MakeTypesInternal;

string tempFile = Path.GetTempFileName();

Expand Down
1 change: 1 addition & 0 deletions ODataConnectedService/src/Models/ServiceConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ internal class ServiceConfiguration
public bool UseNameSpacePrefix { get; set; }
public string NamespacePrefix { get; set; }
public bool UseDataServiceCollection { get; set; }
public bool MakeTypesInternal { get; set; }
}

internal class ServiceConfigurationV4 : ServiceConfiguration
Expand Down
9 changes: 7 additions & 2 deletions ODataConnectedService/src/ODataConnectedService.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
<OldToolsVersion>14.0</OldToolsVersion>
<TargetFrameworkProfile />
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
Expand All @@ -36,11 +37,11 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Microsoft.OData.ConnectedService</RootNamespace>
<AssemblyName>Microsoft.OData.ConnectedService</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<GeneratePkgDefFile>false</GeneratePkgDefFile>
<StartAction>Program</StartAction>
<StartProgram>C:\Program Files (x86)\Microsoft Visual Studio $(VisualStudioVersion)\Common7\IDE\devenv.exe</StartProgram>
<StartProgram>$(DevEnvDir)devenv.exe</StartProgram>
<StartArguments>/rootSuffix exp</StartArguments>
<SignAssembly>true</SignAssembly>
<DelaySign>true</DelaySign>
Expand Down Expand Up @@ -161,6 +162,8 @@
</ItemGroup>
<ItemGroup>
<Compile Include="CodeGeneration\BaseCodeGenDescriptor.cs" />
<Compile Include="CodeGeneration\CodeGenDescriptorFactory.cs" />
<Compile Include="CodeGeneration\ICodeGenDescriptorFactory.cs" />
<Compile Include="CodeGeneration\V3CodeGenDescriptor.cs" />
<Compile Include="CodeGeneration\V4CodeGenDescriptor.cs" />
<Compile Include="Common\CodeGeneratorUtils.cs" />
Expand All @@ -175,11 +178,13 @@
<Compile Include="ODataConnectedServiceProvider.cs" />
<Compile Include="ODataConnectedServiceWizard.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Templates\IODataT4CodeGeneratorFactory.cs" />
<Compile Include="Templates\ODataT4CodeGenerator.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>ODataT4CodeGenerator.tt</DependentUpon>
</Compile>
<Compile Include="Templates\ODataT4CodeGeneratorFactory.cs" />
<Compile Include="ViewModels\AdvancedSettingsViewModel.cs" />
<Compile Include="ViewModels\ConfigODataEndpointViewModel.cs" />
<Compile Include="Views\AdvancedSettings.xaml.cs">
Expand Down
50 changes: 21 additions & 29 deletions ODataConnectedService/src/ODataConnectedServiceHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
using System.Globalization;
using System.Threading;
using System.Threading.Tasks;
using EnvDTE;
Expand All @@ -16,51 +15,44 @@ namespace Microsoft.OData.ConnectedService
[ConnectedServiceHandlerExport(Common.Constants.ProviderId, AppliesTo = "CSharp")]
internal class ODataConnectedServiceHandler : ConnectedServiceHandler
{
public override async Task<AddServiceInstanceResult> AddServiceInstanceAsync(ConnectedServiceHandlerContext context, CancellationToken ct)
{
Project project = ProjectHelper.GetProjectFromHierarchy(context.ProjectHierarchy);
ODataConnectedServiceInstance codeGenInstance = (ODataConnectedServiceInstance)context.ServiceInstance;
private ICodeGenDescriptorFactory codeGenDescriptorFactory;
public ODataConnectedServiceHandler(): this(new CodeGenDescriptorFactory()) {}

var codeGenDescriptor = await GenerateCode(codeGenInstance.MetadataTempFilePath, codeGenInstance.ServiceConfig.EdmxVersion, context, project);
public ODataConnectedServiceHandler(ICodeGenDescriptorFactory codeGenDescriptorFactory)
: base()
{
this.codeGenDescriptorFactory = codeGenDescriptorFactory;
}

context.SetExtendedDesignerData<ServiceConfiguration>(codeGenInstance.ServiceConfig);

public override async Task<AddServiceInstanceResult> AddServiceInstanceAsync(ConnectedServiceHandlerContext context, CancellationToken ct)
{
var codeGenDescriptor = await SaveServiceInstanceAsync(context);
var result = new AddServiceInstanceResult(
context.ServiceInstance.Name,
new Uri(codeGenDescriptor.ClientDocUri));

return result;
}

public override async Task<UpdateServiceInstanceResult> UpdateServiceInstanceAsync(ConnectedServiceHandlerContext context, CancellationToken ct)
{
Project project = ProjectHelper.GetProjectFromHierarchy(context.ProjectHierarchy);
ODataConnectedServiceInstance codeGenInstance = (ODataConnectedServiceInstance)context.ServiceInstance;

var codeGenDescriptor = await GenerateCode(codeGenInstance.ServiceConfig.Endpoint, codeGenInstance.ServiceConfig.EdmxVersion, context, project);
context.SetExtendedDesignerData<ServiceConfiguration>(codeGenInstance.ServiceConfig);
await SaveServiceInstanceAsync(context);
return new UpdateServiceInstanceResult();
}

private static async Task<BaseCodeGenDescriptor> GenerateCode(string metadataUri, Version edmxVersion, ConnectedServiceHandlerContext context, Project project)
private async Task<BaseCodeGenDescriptor> SaveServiceInstanceAsync(ConnectedServiceHandlerContext context)
{
BaseCodeGenDescriptor codeGenDescriptor;
Project project = ProjectHelper.GetProjectFromHierarchy(context.ProjectHierarchy);
ODataConnectedServiceInstance serviceInstance = (ODataConnectedServiceInstance)context.ServiceInstance;

if (edmxVersion == Common.Constants.EdmxVersion1
|| edmxVersion == Common.Constants.EdmxVersion2
|| edmxVersion == Common.Constants.EdmxVersion3)
{
codeGenDescriptor = new V3CodeGenDescriptor(metadataUri, context, project);
}
else if (edmxVersion == Common.Constants.EdmxVersion4)
{
codeGenDescriptor = new V4CodeGenDescriptor(metadataUri, context, project);
}
else
{
throw new Exception(string.Format(CultureInfo.InvariantCulture, "Not supported Edmx Version {0}", edmxVersion.ToString()));
}
var codeGenDescriptor = await GenerateCode(serviceInstance.ServiceConfig.Endpoint, serviceInstance.ServiceConfig.EdmxVersion, context, project);
context.SetExtendedDesignerData<ServiceConfiguration>(serviceInstance.ServiceConfig);
return codeGenDescriptor;
}

private async Task<BaseCodeGenDescriptor> GenerateCode(string metadataUri, Version edmxVersion, ConnectedServiceHandlerContext context, Project project)
{
BaseCodeGenDescriptor codeGenDescriptor = codeGenDescriptorFactory.Create(edmxVersion, metadataUri, context, project);
await codeGenDescriptor.AddNugetPackages();
await codeGenDescriptor.AddGeneratedClientCode();
return codeGenDescriptor;
Expand Down
14 changes: 7 additions & 7 deletions ODataConnectedService/src/ODataConnectedServiceProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ internal class ODataConnectedServiceProvider : ConnectedServiceProvider
{
public ODataConnectedServiceProvider()
{
this.Name = "OData Connected Service";
this.Category = "OData";
this.Description = "OData Connected Service for V1-V4";
this.Icon = new BitmapImage(new Uri("pack://application:,,/" + this.GetType().Assembly.ToString() + ";component/Resources/Icon.png"));
this.CreatedBy = "OData";
this.Version = new Version(0, 2, 0);
this.MoreInfoUri = new Uri("https://github.com/odata/lab");
Name = "OData Connected Service";
Category = "OData";
Description = "OData Connected Service for V1-V4";
Icon = new BitmapImage(new Uri("pack://application:,,/" + this.GetType().Assembly.ToString() + ";component/Resources/Icon.png"));
CreatedBy = "OData";
Version = new Version(0, 4, 0);
MoreInfoUri = new Uri("https://github.com/odata/lab");
}

public override Task<ConnectedServiceConfigurator> CreateConfiguratorAsync(ConnectedServiceProviderContext context)
Expand Down
4 changes: 2 additions & 2 deletions ODataConnectedService/src/ODataConnectedServiceWizard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@

using System;
using System.Threading.Tasks;
using EnvDTE;
using Microsoft.OData.ConnectedService.Common;
using Microsoft.OData.ConnectedService.Models;
using Microsoft.OData.ConnectedService.ViewModels;
using Microsoft.OData.ConnectedService.Views;
Expand Down Expand Up @@ -83,6 +81,7 @@ public ODataConnectedServiceWizard(ConnectedServiceProviderContext context)
advancedSettingsViewModel.IgnoreUnexpectedElementsAndAttributes = serviceConfig.IgnoreUnexpectedElementsAndAttributes;
advancedSettingsViewModel.EnableNamingAlias = serviceConfig.EnableNamingAlias;
advancedSettingsViewModel.IncludeT4File = serviceConfig.IncludeT4File;
advancedSettingsViewModel.MakeTypesInternal = serviceConfig.MakeTypesInternal;
advancedSettings.IncludeT4File.IsEnabled = false;
}
}
Expand Down Expand Up @@ -132,6 +131,7 @@ private ServiceConfiguration CreateServiceConfiguration()
serviceConfiguration.UseDataServiceCollection = AdvancedSettingsViewModel.UseDataServiceCollection;
serviceConfiguration.GeneratedFileNamePrefix = AdvancedSettingsViewModel.GeneratedFileName;
serviceConfiguration.UseNameSpacePrefix = AdvancedSettingsViewModel.UseNamespacePrefix;
serviceConfiguration.MakeTypesInternal = AdvancedSettingsViewModel.MakeTypesInternal;
if (AdvancedSettingsViewModel.UseNamespacePrefix && !string.IsNullOrEmpty(AdvancedSettingsViewModel.NamespacePrefix))
{
serviceConfiguration.NamespacePrefix = AdvancedSettingsViewModel.NamespacePrefix;
Expand Down
3 changes: 3 additions & 0 deletions ODataConnectedService/src/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
Expand Down Expand Up @@ -37,3 +38,5 @@
[assembly: AssemblyVersion("0.3.0.0")]
[assembly: AssemblyFileVersion("0.3.0.0")]
[assembly: NeutralResourcesLanguageAttribute("en")]

[assembly: InternalsVisibleTo("ODataConnectedService.Tests")]
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

namespace Microsoft.OData.ConnectedService.Templates
{
interface IODataT4CodeGeneratorFactory
{
ODataT4CodeGenerator Create();
}
}
Loading