diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4ee9a30..2084648 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,4 +1,4 @@ -name: Build +name: Build on: pull_request: @@ -63,10 +63,10 @@ jobs: run: dotnet build -o ../build/net6.0/ -f net6.0 -c Release --no-restore -m:1 - name: Restore NuGet packages - run: dotnet restore EAVFramework.sln -p:TargetFramework=netcoreapp3.1 + run: dotnet restore EAVFramework.sln -p:TargetFramework=net8.0 - name: Build solution - run: dotnet build -o ../build/netcoreapp3.1/ -f netcoreapp3.1 -c Release --no-restore -m:1 + run: dotnet build -o ../build/net8.0/ -f net8.0 -c Release --no-restore -m:1 - name: Archive build to artifacts uses: actions/upload-artifact@v2 diff --git a/sdk/DTO/AttributeDefinition.cs b/sdk/DTO/AttributeDefinition.cs index bdd193b..5ba25cf 100644 --- a/sdk/DTO/AttributeDefinition.cs +++ b/sdk/DTO/AttributeDefinition.cs @@ -19,8 +19,11 @@ public override AttributeDefinitionBase Read( return new AttributeStringDefinition { Value = reader.GetString() ?? "" }; case JsonTokenType.StartObject: var node = JsonNode.Parse(ref reader); - var t = node.Deserialize(); - return t; + + var t = node.Deserialize(new JsonSerializerOptions { Converters={ new TypeDefinitionConverter()} }); + return t; + + default: throw new Exception($"{reader.TokenType} is not supported as AttributeDefinition"); } @@ -51,10 +54,12 @@ public class AttributeStringDefinition : AttributeDefinitionBase { public string Value { get; set; } } + public class AttributeObjectDefinition : AttributeDefinitionBase { [JsonPropertyName("isPrimaryField")] public bool IsPrimaryField { get; set; } + [JsonPropertyName("logicalName")] public string LogicalName { get; set; } [JsonPropertyName("moduleSource")] public string ModuleSource { get; set; } @@ -69,9 +74,52 @@ public class AttributeObjectDefinition : AttributeDefinitionBase public Dictionary AdditionalFields { get; set; } } - public class TypeDefinition + + public class TypeDefinitionConverter : JsonConverter + { + public override TypeDefinition Read( + ref Utf8JsonReader reader, + Type typeToConvert, + JsonSerializerOptions options) + { + switch (reader.TokenType) + { + case JsonTokenType.String: + return new TypeDefinition { Type = reader.GetString() ?? "" }; + case JsonTokenType.StartObject: + var node = JsonNode.Parse(ref reader); + + var t = node.Deserialize(); + return t; + + + default: + throw new Exception($"{reader.TokenType} is not supported as AttributeDefinition"); + } + } + + public override void Write(Utf8JsonWriter writer, TypeDefinition value, JsonSerializerOptions options) + { + var jsonString = value switch + { + TypeDefinition attributeObjectDefinition => + JsonSerializer.Serialize(attributeObjectDefinition), + + _ => throw new ArgumentException($"{value.GetType()} is not supported") + }; + + var jsonNode = JsonNode.Parse(jsonString); + jsonNode?.WriteTo(writer, options); + } + } + + // [JsonConverter(typeof(TypeDefinitionConverter))] + + public class TypeDefinition { [JsonPropertyName("type")] public string Type { get; set; } + + [JsonPropertyName("split")] public bool Split { get; set; } [JsonPropertyName("referenceType")] public string ReferenceType { get; set; } [JsonPropertyName("options")] public Dictionary Options { get; set; } diff --git a/sdk/DTO/EntityDefinition.cs b/sdk/DTO/EntityDefinition.cs index 836264c..7a0242d 100644 --- a/sdk/DTO/EntityDefinition.cs +++ b/sdk/DTO/EntityDefinition.cs @@ -1,3 +1,4 @@ +using Newtonsoft.Json; using System.Collections.Generic; using System.Text.Json.Serialization; @@ -5,15 +6,36 @@ namespace EAVFW.Extensions.Manifest.SDK { public class EntityDefinition { - [JsonPropertyName("pluralName")] public string PluralName { get; set; } - [JsonPropertyName("description")] public string Description { get; set; } - [JsonPropertyName("attributes")] public Dictionary Attributes { get; set; } - [JsonPropertyName("wizards")] public Dictionary Wizards { get; set; } + [JsonProperty("pluralName")] + [JsonPropertyName("pluralName")] + public string PluralName { get; set; } + + [JsonProperty("collectionSchemaName")] + [JsonPropertyName("collectionSchemaName")] + public string CollectionSchemaName { get; set; } + + [JsonProperty("logicalName")] + [JsonPropertyName("logicalName")] + public string LogicalName { get; set; } + + + [JsonPropertyName("description")] + [JsonProperty("description")] + public string Description { get; set; } + + [JsonPropertyName("attributes")] + [JsonProperty("attributes")] + public Dictionary Attributes { get; set; } + + [JsonPropertyName("wizards")] + [JsonProperty("wizards")] + public Dictionary Wizards { get; set; } /// /// Exclusively used to capture non-spec items /// - [JsonExtensionData] + [System.Text.Json.Serialization.JsonExtensionData] + [Newtonsoft.Json.JsonExtensionData] public Dictionary AdditionalFields { get; set; } } } diff --git a/sdk/DTO/MessageDefinition.cs b/sdk/DTO/MessageDefinition.cs index 8a3ed1d..a6ccecb 100644 --- a/sdk/DTO/MessageDefinition.cs +++ b/sdk/DTO/MessageDefinition.cs @@ -4,6 +4,6 @@ namespace EAVFW.Extensions.Manifest.SDK { public class MessageDefinition { - [JsonPropertyName("title")] public string? Title { get; set; } + [JsonPropertyName("title")] public string Title { get; set; } } } diff --git a/sdk/DefaultManifestReplacementRunner.cs b/sdk/DefaultManifestReplacementRunner.cs index 2df0862..e4a531e 100644 --- a/sdk/DefaultManifestReplacementRunner.cs +++ b/sdk/DefaultManifestReplacementRunner.cs @@ -1,4 +1,4 @@ -using DotNETDevOps.JsonFunctions; +using DotNETDevOps.JsonFunctions; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Newtonsoft.Json.Linq; @@ -211,14 +211,10 @@ public async Task RunReplacements(JToken jsonraw, string customizationprefix, IL } else { - try - { + parentObj.Add(childProp); q.Enqueue(childProp); - }catch(Exception ex) - { - throw; - } + } // parentObj.Add(childProp.Name, childProp.Value); @@ -284,7 +280,7 @@ public async Task RunReplacements(JToken jsonraw, string customizationprefix, IL } } - catch (Exception ex) + catch (Exception) { Console.WriteLine($"{entityPath}| {attributePath}"); throw; diff --git a/sdk/EAVFW.Extensions.Manifest.SDK.csproj b/sdk/EAVFW.Extensions.Manifest.SDK.csproj index d83c851..5a386c7 100644 --- a/sdk/EAVFW.Extensions.Manifest.SDK.csproj +++ b/sdk/EAVFW.Extensions.Manifest.SDK.csproj @@ -1,7 +1,7 @@ - + - netcoreapp3.1;net6.0;net8.0 + net6.0;net8.0 disable disable diff --git a/sdk/ManifestEnricher.cs b/sdk/ManifestEnricher.cs index 8451f01..1236a87 100644 --- a/sdk/ManifestEnricher.cs +++ b/sdk/ManifestEnricher.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; @@ -45,7 +45,7 @@ public ManifestPermissionGenerator(IParameterGenerator parameterGenerator) { this.parameterGenerator = parameterGenerator ?? throw new ArgumentNullException(nameof(parameterGenerator)); } - public async Task CreateInitializationScript(JToken model, string systemUserEntity) + public Task CreateInitializationScript(JToken model, string systemUserEntity) { var sb = new StringBuilder(); @@ -80,7 +80,7 @@ public async Task CreateInitializationScript(JToken model, string system WritePermissionStatement(sb, entitiy, "Assign", "Assign", adminSGId); } - return sb.ToString(); + return Task.FromResult(sb.ToString()); } private void WritePermissionStatement(StringBuilder sb, JProperty entitiy, string permission, string permissionName, string adminSGId, bool adminSRId1 = false) { @@ -134,7 +134,7 @@ private object[] CreateOptions(params string[] args) { return args.Select((o, i) => new { label = o, value = i + 1 }).ToArray(); } - private JObject CreateAttribute(JObject attr, string displayName, object type, string? schemaName = null, object? additionalProps = null) + private JObject CreateAttribute(JObject attr, string displayName, object type, string schemaName = null, object additionalProps = null) { if (additionalProps != null) return Merge(Merge(attr, new { displayName, type, schemaName }), additionalProps); @@ -178,78 +178,136 @@ public async Task LoadJsonDocumentAsync(JToken jsonraw, string cus var pluralName = name + " References"; //$"{entitieP.Value.SelectToken("$.displayName")} {polyLookup.Value.SelectToken("$.displayName")} References"; var reverse = polyLookup.Value.SelectToken("$.type.reverse")?.ToObject() ?? false; var inline = polyLookup.Value.SelectToken("$.type.inline")?.ToObject() ?? false; - if (!entities.ContainsKey(Key)) - { + var split = polyLookup.Value.SelectToken("$.type.split")?.ToObject() ?? false; + + + + if (split) + { + polyLookup.Value["metadataOnly"] = true; + var attributes = polyLookup.Value.SelectToken("$.type.referenceTypes").ToObject() - .ToDictionary(k => k, v => JToken.FromObject(new { type = new { type = "lookup", referenceType = v } })); + .ToDictionary(k => k, v => JToken.FromObject(new { type = new { type = "lookup", referenceType = v } })); - if (inline) + foreach (var polylookupreference in attributes) { - foreach (var attribute in attributes) + string key = $"{entitieP.Name} {polylookupreference.Key} Reference"; + + entities[key] = JToken.FromObject(new { - entitieP.Value["attributes"][attribute.Key] = attribute.Value; + pluralName = key + "s", + attributes = new Dictionary + { + [polylookupreference.Key] = new + { + type = new + { + type = "lookup", + referenceType = polylookupreference.Key + } + }, + [entitieP.Name] = new + { + type = new + { + type = "lookup", + referenceType = entitieP.Name, + index = new { unique=true}, + cascade = new + { + delete= "cascade" + } + } + } + } + }); + + SetRequiredProps(entities[key] as JObject, key); - } - polyLookup.Value["type"]["type"] = "polylookup"; - // polyLookup.Remove(); + await EnrichEntity(jsonraw, customizationprefix, logger, insertMerges, entities[key] as JObject); } - else - { + //polyLookup.Remove(); + } + else + { - // attributes["Id"] = JToken.FromObject(new { isPrimaryKey = true }); - attributes["Name"] = JToken.FromObject(new { isPrimaryField = true }); + if (!entities.ContainsKey(Key)) + { + var attributes = polyLookup.Value.SelectToken("$.type.referenceTypes").ToObject() + .ToDictionary(k => k, v => JToken.FromObject(new { type = new { type = "lookup", referenceType = v } })); + if (inline) + { + foreach (var attribute in attributes) + { + entitieP.Value["attributes"][attribute.Key] = attribute.Value; - entities[Key] = JToken.FromObject(new + } + polyLookup.Value["type"]["type"] = "polylookup"; + + // polyLookup.Remove(); + } + else { - pluralName = pluralName, - attributes = attributes - }); - SetRequiredProps(entities[Key] as JObject, Key); + // attributes["Id"] = JToken.FromObject(new { isPrimaryKey = true }); + attributes["Name"] = JToken.FromObject(new { isPrimaryField = true }); + + + + entities[Key] = JToken.FromObject(new + { + pluralName = pluralName, + attributes = attributes + }); + + + SetRequiredProps(entities[Key] as JObject, Key); + } } - } - if (!inline) - { - var entity = entities[Key] as JObject; - polyLookup.Value["type"]["foreignKey"] = JToken.FromObject(new + if (!inline) { - principalTable = entity["logicalName"].ToString(), - principalColumn = "id", - principalNameColumn = "name", - name = TrimId(polyLookup.Value.SelectToken("$.logicalName")?.ToString()) // jsonraw.SelectToken($"$.entities['{ attr["type"]["referenceType"] }'].logicalName").ToString().Replace(" ", ""), - }); - polyLookup.Value["type"]["referenceType"] = Key; + var entity = entities[Key] as JObject; + polyLookup.Value["type"]["foreignKey"] = JToken.FromObject(new + { + principalTable = entity["logicalName"].ToString(), + principalColumn = "id", + principalNameColumn = "name", + name = TrimId(polyLookup.Value.SelectToken("$.logicalName")?.ToString()) // jsonraw.SelectToken($"$.entities['{ attr["type"]["referenceType"] }'].logicalName").ToString().Replace(" ", ""), + }); + polyLookup.Value["type"]["referenceType"] = Key; - if (reverse) - { - entities[Key]["attributes"][polyLookup.Name] = JToken.FromObject(new + if (reverse) { - type = new + entities[Key]["attributes"][polyLookup.Name] = JToken.FromObject(new { - type = "lookup", - referenceType = entitieP.Name - } - }); + type = new + { + type = "lookup", + referenceType = entitieP.Name + } + }); - // polyLookup.Remove(); - } + // polyLookup.Remove(); + } - // polyLookup.Value["type"]["type"] = "lookup"; + // polyLookup.Value["type"]["type"] = "lookup"; - await EnrichEntity(jsonraw, customizationprefix, logger, insertMerges, entity); - } - else - { + await EnrichEntity(jsonraw, customizationprefix, logger, insertMerges, entity); + } + else + { + - await EnrichEntity(jsonraw, customizationprefix, logger, insertMerges, entitieP.Value as JObject); + await EnrichEntity(jsonraw, customizationprefix, logger, insertMerges, entitieP.Value as JObject); + } } } } @@ -719,7 +777,7 @@ JObject SetDefault(JToken obj, JObject localeEnglish) } var queue = - new Queue( + new Queue( attributes.Properties() .Select(c => c.Value as JObject) .Where(x => x != null) diff --git a/src/DynamicContext.cs b/src/DynamicContext.cs index 4d5c230..0e63371 100644 --- a/src/DynamicContext.cs +++ b/src/DynamicContext.cs @@ -3,6 +3,7 @@ using EAVFramework.Endpoints.Query.OData; using EAVFramework.Extensions; using EAVFramework.Shared; +using EAVFW.Extensions.Manifest.SDK; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.OData.Abstracts; @@ -428,6 +429,31 @@ public IQueryable Set(Type type) public EntityEntry Add(string entityName, JToken data) { var type = manager.ModelDefinition.EntityDTOs[entityName]; + + + //Handling Polylookups (Split mode) + if (manager.ModelDefinition.Entities.ContainsKey(entityName)) + { + var entity = manager.ModelDefinition.Entities[entityName]; + foreach(var poly in entity.Attributes.Where(a=>a.Value is AttributeObjectDefinition typeobj && typeobj.AttributeType.Type == "polylookup" && typeobj.AttributeType.Split)) + { + var attr = poly.Value as AttributeObjectDefinition; + var reference = data[attr.LogicalName]?.ToString(); + + if (!string.IsNullOrEmpty(reference)) + { + var referenceType = reference.Substring(0, reference.IndexOf(':')); + var referenceId = reference.Substring(referenceType.Length+1); + data[$"{entity.LogicalName}{referenceType}references"] = new JArray( + new JObject( + new JProperty($"{referenceType}id", referenceId) + ) + ); + } + } + } + + var record = data.ToObject(type); logger.LogInformation("Adding {CLRType} from {rawData} to {typedData}", type.Name, data.ToString(), JsonConvert.SerializeObject(record)); var a = this.Attach(record); diff --git a/src/EAVFramework.csproj b/src/EAVFramework.csproj index ecd4adc..0ff3243 100644 --- a/src/EAVFramework.csproj +++ b/src/EAVFramework.csproj @@ -1,7 +1,7 @@ - netcoreapp3.1;net6.0;net8.0 + net6.0;net8.0 EAVFramework Poul Kjeldager EAVFW diff --git a/src/Endpoints/CreateRecordsEndpoint.cs b/src/Endpoints/CreateRecordsEndpoint.cs index 9583c3b..284d74c 100644 --- a/src/Endpoints/CreateRecordsEndpoint.cs +++ b/src/Endpoints/CreateRecordsEndpoint.cs @@ -1,24 +1,13 @@ -using EAVFramework.Endpoints.Results; +using EAVFramework.Endpoints.Results; using EAVFramework.Hosting; -using EAVFramework.Plugins; -using EAVFramework.Validation; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Routing; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.ChangeTracking; using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.IO; using System.Linq; -using System.Reflection; -using System.Security.Claims; using System.Threading.Tasks; using static EAVFramework.Constants; diff --git a/src/MigrationManager.cs b/src/MigrationManager.cs index c031f48..beebf7a 100644 --- a/src/MigrationManager.cs +++ b/src/MigrationManager.cs @@ -27,6 +27,8 @@ using EAVFramework.Shared.V2; using Microsoft.Extensions.DependencyInjection; using System.IO; +using EAVFW.Extensions.Manifest.SDK; +using System.Text.Json; namespace EAVFramework { @@ -57,6 +59,7 @@ public class ModelDefinition public TypeInfo Type { get; set; } public Func MigrationFactory { get; set; } + public Dictionary Entities { get; set; } } public class MigrationManagerOptions { @@ -370,7 +373,12 @@ private ModelDefinition CreateModel(string migrationName, JToken manifest, Dynam try { - var m = new ModelDefinition(); + var m = new ModelDefinition() + { + Entities = new Dictionary( System.Text.Json.JsonSerializer.Deserialize(manifest.ToString()) + .Entities.ToDictionary(k=>k.Value.CollectionSchemaName, v=>v.Value),StringComparer.OrdinalIgnoreCase) + }; + //var asmb = dynamicCodeService.CreateAssemblyBuilder(options.Namespace); var manfiestservice = new ManifestService(new ManifestServiceOptions { diff --git a/src/Shared/V2/ManifestService.cs b/src/Shared/V2/ManifestService.cs index b73c605..bdf3953 100644 --- a/src/Shared/V2/ManifestService.cs +++ b/src/Shared/V2/ManifestService.cs @@ -282,9 +282,12 @@ internal Type CreateDynamicMigration(DynamicCodeService dynamicCodeService, JTok var table = builder .WithTable(entityDefinition.Name, - tableSchemaname: entityDefinition.Value.SelectToken("$.schemaName").ToString(), - tableLogicalName: entityDefinition.Value.SelectToken("$.logicalName").ToString(), - tableCollectionSchemaName: entityDefinition.Value.SelectToken("$.collectionSchemaName").ToString(), + tableSchemaname: entityDefinition.Value.SelectToken("$.schemaName")?.ToString() + ?? throw new Exception($"Failed to get schemaname for {entityDefinition.Name}"), + tableLogicalName: entityDefinition.Value.SelectToken("$.logicalName")?.ToString() + ?? throw new Exception($"Failed to get logicalname for {entityDefinition.Name}"), + tableCollectionSchemaName: entityDefinition.Value.SelectToken("$.collectionSchemaName")?.ToString() + ?? throw new Exception($"Failed to get collectionSchemaName for {entityDefinition.Name}"), entityDefinition.Value.SelectToken("$.schema")?.ToString() ?? options.Schema, entityDefinition.Value.SelectToken("$.abstract") != null ).External(entityDefinition.Value.SelectToken("$.external")?.ToObject() ?? false, result); @@ -358,6 +361,16 @@ internal Type CreateDynamicMigration(DynamicCodeService dynamicCodeService, JTok if (type == "choices") continue; + if (attributeDefinition.Value.SelectToken("$.metadataOnly")?.ToObject() == true ) + { + /* + * When the poly lookup is split, then there is generted additional + * reference tabels to link things together and migrations is set to false indicating that it can be skipped + */ + continue; + } + + var propertyInfo = table .AddProperty(attributeKey, schemaName, logicalName, type) .WithExternalHash(HashExtensions.Sha256(attributeDefinition.Value.ToString())) @@ -393,9 +406,10 @@ internal Type CreateDynamicMigration(DynamicCodeService dynamicCodeService, JTok */ continue; } - - - propertyInfo + + + + propertyInfo .LookupTo( tables[attributeDefinition.Value.SelectToken("$.type.referenceType")?.ToString()], //attributeDefinition.Value.SelectToken("$.type.foreignKey")?.ToObject(), diff --git a/test/EAVFramework.UnitTest/EAVFramework.UnitTest.csproj b/test/EAVFramework.UnitTest/EAVFramework.UnitTest.csproj index 5781c0d..b2d4439 100644 --- a/test/EAVFramework.UnitTest/EAVFramework.UnitTest.csproj +++ b/test/EAVFramework.UnitTest/EAVFramework.UnitTest.csproj @@ -1,7 +1,7 @@ - + - netcoreapp3.1;net6.0 + net6.0;net8.0 false 5530110b-f598-40fb-a452-3a16fa69df9e @@ -9,10 +9,10 @@ - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/EAVFramework.UnitTest/EmitTests.cs b/test/EAVFramework.UnitTest/EmitTests.cs index 84a5b1c..0b23370 100644 --- a/test/EAVFramework.UnitTest/EmitTests.cs +++ b/test/EAVFramework.UnitTest/EmitTests.cs @@ -1,5 +1,6 @@ -using EAVFramework.Shared; +using EAVFramework.Shared; using EAVFramework.Shared.V2; +using EAVFramework.UnitTest.ManifestTests; using Microsoft.AspNetCore.Cors.Infrastructure; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; @@ -29,7 +30,7 @@ namespace EAVFramework.UnitTest { [TestClass] - public class EmitTests + public class EmitTests : BaseManifestTests { public static string RemoveWhitespace( string input) { @@ -153,6 +154,7 @@ public void TestInherience() } [TestMethod] + [DeploymentItem(@"Specs/oidcclient.json", "Specs")] public void TestCoices() { DynamicCodeService codeMigratorV2 = CreateOptions(o => @@ -324,69 +326,7 @@ public void TestExternalBaseClass() } - private static void NoOp(CodeGenerationOptions o) { } - private static DynamicCodeService CreateOptions(Action onconfig =null) - { - onconfig ??= NoOp; - var o = new CodeGenerationOptions - { - // MigrationName="Initial", - - JsonPropertyAttributeCtor = typeof(JsonPropertyAttribute).GetConstructor(new Type[] { typeof(string) }), - JsonPropertyNameAttributeCtor = typeof(System.Text.Json.Serialization.JsonPropertyNameAttribute).GetConstructor(new Type[] { typeof(string) }), - InverseAttributeCtor = typeof(InversePropertyAttribute).GetConstructor(new Type[] { typeof(string) }), - ForeignKeyAttributeCtor= typeof(ForeignKeyAttribute).GetConstructor(new Type[] { typeof(string) }), - - EntityConfigurationInterface = typeof(IEntityTypeConfiguration), - EntityConfigurationConfigureName = nameof(IEntityTypeConfiguration.Configure), - EntityTypeBuilderType = typeof(EntityTypeBuilder), - EntityTypeBuilderToTable = Resolve(()=> typeof(RelationalEntityTypeBuilderExtensions).GetMethod(nameof(RelationalEntityTypeBuilderExtensions.ToTable), 0, new[] { typeof(EntityTypeBuilder), typeof(string), typeof(string) }), "EntityTypeBuilderToTable"), - EntityTypeBuilderHasKey = Resolve(() => typeof(EntityTypeBuilder).GetMethod(nameof(EntityTypeBuilder.HasKey), 0, new[] { typeof(string[]) }), "EntityTypeBuilderHasKey"), - EntityTypeBuilderPropertyMethod = Resolve(() => typeof(EntityTypeBuilder).GetMethod(nameof(EntityTypeBuilder.Property), 0, new[] { typeof(string) }), "EntityTypeBuilderPropertyMethod"), - - IsRequiredMethod = Resolve(() => typeof(Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder) - .GetMethod(nameof(Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder.IsRequired)), "IsRequiredMethod"), - IsRowVersionMethod = Resolve(() => typeof(Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder) - .GetMethod(nameof(Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder.IsRowVersion)), "IsRowVersionMethod"), - HasConversionMethod = Resolve(() => typeof(Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder) - .GetMethod(nameof(Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder.HasConversion), 1, new Type[] { }), "HasConversionMethod"), - HasPrecisionMethod = Resolve(() => typeof(Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder) - .GetMethod(nameof(Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder.HasPrecision), new Type[] { typeof(int), typeof(int) }), "HasPrecisionMethod"), - - - - DynamicTableType = typeof(IDynamicTable), - DynamicTableArrayType = typeof(IDynamicTable[]), - - - ColumnsBuilderType = typeof(ColumnsBuilder), - CreateTableBuilderType = typeof(CreateTableBuilder<>), - CreateTableBuilderPrimaryKeyName = nameof(CreateTableBuilder.PrimaryKey), - CreateTableBuilderForeignKeyName = nameof(CreateTableBuilder.ForeignKey), - ColumnsBuilderColumnMethod = Resolve(() => typeof(ColumnsBuilder).GetMethod(nameof(ColumnsBuilder.Column), BindingFlags.Public | BindingFlags.Instance), "ColumnsBuilderColumnMethod"), - OperationBuilderAddColumnOptionType = typeof(OperationBuilder), - - - MigrationBuilderDropTable = Resolve(() => typeof(MigrationBuilder).GetMethod(nameof(MigrationBuilder.DropTable)), "MigrationBuilderDropTable"), - MigrationBuilderCreateTable = Resolve(() => typeof(MigrationBuilder).GetMethod(nameof(MigrationBuilder.CreateTable)), "MigrationBuilderCreateTable"), - MigrationBuilderSQL = Resolve(() => typeof(MigrationBuilder).GetMethod(nameof(MigrationBuilder.Sql)), "MigrationBuilderSQL"), - MigrationBuilderCreateIndex = Resolve(() => typeof(MigrationBuilder).GetMethod(nameof(MigrationBuilder.CreateIndex), new Type[] { typeof(string), typeof(string), typeof(string[]), typeof(string), typeof(bool), typeof(string) }), "MigrationBuilderCreateIndex"), - MigrationBuilderDropIndex = Resolve(() => typeof(MigrationBuilder).GetMethod(nameof(MigrationBuilder.DropIndex)), "MigrationBuilderDropIndex"), - MigrationsBuilderAddColumn = Resolve(() => typeof(MigrationBuilder).GetMethod(nameof(MigrationBuilder.AddColumn)), "MigrationsBuilderAddColumn"), - MigrationsBuilderAddForeignKey = Resolve(() => typeof(MigrationBuilder).GetMethod(nameof(MigrationBuilder.AddForeignKey), new Type[] { typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(ReferentialAction), typeof(ReferentialAction) }), "MigrationsBuilderAddForeignKey"), - MigrationsBuilderAlterColumn = Resolve(() => typeof(MigrationBuilder).GetMethod(nameof(MigrationBuilder.AlterColumn)), "MigrationsBuilderAlterColumn"), - MigrationsBuilderDropForeignKey = Resolve(() => typeof(MigrationBuilder).GetMethod(nameof(MigrationBuilder.DropForeignKey)), "MigrationsBuilderDropForeignKey"), - - ReferentialActionType = typeof(ReferentialAction), - ReferentialActionNoAction = (int)ReferentialAction.NoAction, - - - LambdaBase = Resolve(() => typeof(Expression).GetMethod(nameof(Expression.Lambda), 1, BindingFlags.Public | BindingFlags.Static, null, new[] { typeof(Expression), typeof(ParameterExpression[]) }, null), "LambdaBase"), - - }; - onconfig(o); - return new DynamicCodeService(o); - } + } [EntityInterface(EntityKey ="*")] diff --git a/test/EAVFramework.UnitTest/GenericTests.cs b/test/EAVFramework.UnitTest/GenericTests.cs index e5c4da9..e7351ff 100644 --- a/test/EAVFramework.UnitTest/GenericTests.cs +++ b/test/EAVFramework.UnitTest/GenericTests.cs @@ -1,6 +1,7 @@ -using EAVFramework.Shared; +using EAVFramework.Shared; using EAVFramework.Shared.V2; using EAVFramework.UnitTest.ManifestTests; +using EAVFW.Extensions.Manifest.SDK; using Microsoft.VisualStudio.TestTools.UnitTesting; using Newtonsoft.Json.Linq; using System; @@ -11,6 +12,7 @@ using System.Reflection; using System.Reflection.Emit; using System.Text; +using System.Text.Json; using System.Threading.Tasks; using System.Xml.Linq; @@ -104,8 +106,8 @@ public static string RemoveWhitespace(string input) public async Task TestInherienceLevel2() { //Arrange - var manifest = JToken.Parse(File.ReadAllText(@"Specs/manifest.payments.json")); - + var manifest = JToken.Parse(File.ReadAllText(@"Specs/manifest.payments.json")); + //Act var sql = RunDBWithSchema("payments", manifest); diff --git a/test/EAVFramework.UnitTest/ManifestTests/BaseManifestTests.cs b/test/EAVFramework.UnitTest/ManifestTests/BaseManifestTests.cs index ad97bd1..ce7077f 100644 --- a/test/EAVFramework.UnitTest/ManifestTests/BaseManifestTests.cs +++ b/test/EAVFramework.UnitTest/ManifestTests/BaseManifestTests.cs @@ -1,4 +1,4 @@ -using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -28,63 +28,65 @@ private static void NoOp(CodeGenerationOptions o) { } protected static DynamicCodeService CreateOptions(Action onconfig = null) { onconfig ??= NoOp; - var o = new CodeGenerationOptions - { - // MigrationName="Initial", + //var o = new CodeGenerationOptions + //{ + // // MigrationName="Initial", - JsonPropertyAttributeCtor = typeof(JsonPropertyAttribute).GetConstructor(new Type[] { typeof(string) }), - JsonPropertyNameAttributeCtor = typeof(System.Text.Json.Serialization.JsonPropertyNameAttribute).GetConstructor(new Type[] { typeof(string) }), - InverseAttributeCtor = typeof(InversePropertyAttribute).GetConstructor(new Type[] { typeof(string) }), - ForeignKeyAttributeCtor = typeof(ForeignKeyAttribute).GetConstructor(new Type[] { typeof(string) }), + // JsonPropertyAttributeCtor = typeof(JsonPropertyAttribute).GetConstructor(new Type[] { typeof(string) }), + // JsonPropertyNameAttributeCtor = typeof(System.Text.Json.Serialization.JsonPropertyNameAttribute).GetConstructor(new Type[] { typeof(string) }), + // InverseAttributeCtor = typeof(InversePropertyAttribute).GetConstructor(new Type[] { typeof(string) }), + // ForeignKeyAttributeCtor = typeof(ForeignKeyAttribute).GetConstructor(new Type[] { typeof(string) }), - EntityConfigurationInterface = typeof(IEntityTypeConfiguration), - EntityConfigurationConfigureName = nameof(IEntityTypeConfiguration.Configure), - EntityTypeBuilderType = typeof(EntityTypeBuilder), - EntityTypeBuilderToTable = Resolve(() => typeof(RelationalEntityTypeBuilderExtensions).GetMethod(nameof(RelationalEntityTypeBuilderExtensions.ToTable), 0, new[] { typeof(EntityTypeBuilder), typeof(string), typeof(string) }), "EntityTypeBuilderToTable"), - EntityTypeBuilderHasKey = Resolve(() => typeof(EntityTypeBuilder).GetMethod(nameof(EntityTypeBuilder.HasKey), 0, new[] { typeof(string[]) }), "EntityTypeBuilderHasKey"), - EntityTypeBuilderPropertyMethod = Resolve(() => typeof(EntityTypeBuilder).GetMethod(nameof(EntityTypeBuilder.Property), 0, new[] { typeof(string) }), "EntityTypeBuilderPropertyMethod"), + // EntityConfigurationInterface = typeof(IEntityTypeConfiguration), + // EntityConfigurationConfigureName = nameof(IEntityTypeConfiguration.Configure), + // EntityTypeBuilderType = typeof(EntityTypeBuilder), + // EntityTypeBuilderToTable = Resolve(() => typeof(RelationalEntityTypeBuilderExtensions).GetMethod(nameof(RelationalEntityTypeBuilderExtensions.ToTable), 0, new[] { typeof(EntityTypeBuilder), typeof(string), typeof(string) }), "EntityTypeBuilderToTable"), + // EntityTypeBuilderHasKey = Resolve(() => typeof(EntityTypeBuilder).GetMethod(nameof(EntityTypeBuilder.HasKey), 0, new[] { typeof(string[]) }), "EntityTypeBuilderHasKey"), + // EntityTypeBuilderPropertyMethod = Resolve(() => typeof(EntityTypeBuilder).GetMethod(nameof(EntityTypeBuilder.Property), 0, new[] { typeof(string) }), "EntityTypeBuilderPropertyMethod"), - IsRequiredMethod = Resolve(() => typeof(Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder) - .GetMethod(nameof(Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder.IsRequired)), "IsRequiredMethod"), - IsRowVersionMethod = Resolve(() => typeof(Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder) - .GetMethod(nameof(Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder.IsRowVersion)), "IsRowVersionMethod"), - HasConversionMethod = Resolve(() => typeof(Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder) - .GetMethod(nameof(Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder.HasConversion), 1, new Type[] { }), "HasConversionMethod"), - HasPrecisionMethod = Resolve(() => typeof(Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder) - .GetMethod(nameof(Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder.HasPrecision), new Type[] { typeof(int), typeof(int) }), "HasPrecisionMethod"), + // IsRequiredMethod = Resolve(() => typeof(Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder) + // .GetMethod(nameof(Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder.IsRequired)), "IsRequiredMethod"), + // IsRowVersionMethod = Resolve(() => typeof(Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder) + // .GetMethod(nameof(Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder.IsRowVersion)), "IsRowVersionMethod"), + // HasConversionMethod = Resolve(() => typeof(Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder) + // .GetMethod(nameof(Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder.HasConversion), 1, new Type[] { }), "HasConversionMethod"), + // HasPrecisionMethod = Resolve(() => typeof(Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder) + // .GetMethod(nameof(Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder.HasPrecision), new Type[] { typeof(int), typeof(int) }), "HasPrecisionMethod"), - DynamicTableType = typeof(IDynamicTable), - DynamicTableArrayType = typeof(IDynamicTable[]), + // DynamicTableType = typeof(IDynamicTable), + // DynamicTableArrayType = typeof(IDynamicTable[]), - ColumnsBuilderType = typeof(ColumnsBuilder), - CreateTableBuilderType = typeof(CreateTableBuilder<>), - CreateTableBuilderPrimaryKeyName = nameof(CreateTableBuilder.PrimaryKey), - CreateTableBuilderForeignKeyName = nameof(CreateTableBuilder.ForeignKey), - ColumnsBuilderColumnMethod = Resolve(() => typeof(ColumnsBuilder).GetMethod(nameof(ColumnsBuilder.Column), BindingFlags.Public | BindingFlags.Instance), "ColumnsBuilderColumnMethod"), - OperationBuilderAddColumnOptionType = typeof(OperationBuilder), + // ColumnsBuilderType = typeof(ColumnsBuilder), + // CreateTableBuilderType = typeof(CreateTableBuilder<>), + // CreateTableBuilderPrimaryKeyName = nameof(CreateTableBuilder.PrimaryKey), + // CreateTableBuilderForeignKeyName = nameof(CreateTableBuilder.ForeignKey), + // ColumnsBuilderColumnMethod = Resolve(() => typeof(ColumnsBuilder).GetMethod(nameof(ColumnsBuilder.Column), BindingFlags.Public | BindingFlags.Instance), "ColumnsBuilderColumnMethod"), + // OperationBuilderAddColumnOptionType = typeof(OperationBuilder), - MigrationBuilderDropTable = Resolve(() => typeof(MigrationBuilder).GetMethod(nameof(MigrationBuilder.DropTable)), "MigrationBuilderDropTable"), - MigrationBuilderCreateTable = Resolve(() => typeof(MigrationBuilder).GetMethod(nameof(MigrationBuilder.CreateTable)), "MigrationBuilderCreateTable"), - MigrationBuilderSQL = Resolve(() => typeof(MigrationBuilder).GetMethod(nameof(MigrationBuilder.Sql)), "MigrationBuilderSQL"), - MigrationBuilderCreateIndex = Resolve(() => typeof(MigrationBuilder).GetMethod(nameof(MigrationBuilder.CreateIndex), new Type[] { typeof(string), typeof(string), typeof(string[]), typeof(string), typeof(bool), typeof(string) }), "MigrationBuilderCreateIndex"), - MigrationBuilderDropIndex = Resolve(() => typeof(MigrationBuilder).GetMethod(nameof(MigrationBuilder.DropIndex)), "MigrationBuilderDropIndex"), - MigrationsBuilderAddColumn = Resolve(() => typeof(MigrationBuilder).GetMethod(nameof(MigrationBuilder.AddColumn)), "MigrationsBuilderAddColumn"), - MigrationsBuilderAddForeignKey = Resolve(() => typeof(MigrationBuilder).GetMethod(nameof(MigrationBuilder.AddForeignKey), new Type[] { typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(ReferentialAction), typeof(ReferentialAction) }), "MigrationsBuilderAddForeignKey"), - MigrationsBuilderAlterColumn = Resolve(() => typeof(MigrationBuilder).GetMethod(nameof(MigrationBuilder.AlterColumn)), "MigrationsBuilderAlterColumn"), - MigrationsBuilderDropForeignKey = Resolve(() => typeof(MigrationBuilder).GetMethod(nameof(MigrationBuilder.DropForeignKey)), "MigrationsBuilderDropForeignKey"), + // MigrationBuilderDropTable = Resolve(() => typeof(MigrationBuilder).GetMethod(nameof(MigrationBuilder.DropTable)), "MigrationBuilderDropTable"), + // MigrationBuilderCreateTable = Resolve(() => typeof(MigrationBuilder).GetMethod(nameof(MigrationBuilder.CreateTable)), "MigrationBuilderCreateTable"), + // MigrationBuilderSQL = Resolve(() => typeof(MigrationBuilder).GetMethod(nameof(MigrationBuilder.Sql)), "MigrationBuilderSQL"), + // MigrationBuilderCreateIndex = Resolve(() => typeof(MigrationBuilder).GetMethod(nameof(MigrationBuilder.CreateIndex), new Type[] { typeof(string), typeof(string), typeof(string[]), typeof(string), typeof(bool), typeof(string) }), "MigrationBuilderCreateIndex"), + // MigrationBuilderDropIndex = Resolve(() => typeof(MigrationBuilder).GetMethod(nameof(MigrationBuilder.DropIndex)), "MigrationBuilderDropIndex"), + // MigrationsBuilderAddColumn = Resolve(() => typeof(MigrationBuilder).GetMethod(nameof(MigrationBuilder.AddColumn)), "MigrationsBuilderAddColumn"), + // MigrationsBuilderAddForeignKey = Resolve(() => typeof(MigrationBuilder).GetMethod(nameof(MigrationBuilder.AddForeignKey), new Type[] { typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(ReferentialAction), typeof(ReferentialAction) }), "MigrationsBuilderAddForeignKey"), + // MigrationsBuilderAlterColumn = Resolve(() => typeof(MigrationBuilder).GetMethod(nameof(MigrationBuilder.AlterColumn)), "MigrationsBuilderAlterColumn"), + // MigrationsBuilderDropForeignKey = Resolve(() => typeof(MigrationBuilder).GetMethod(nameof(MigrationBuilder.DropForeignKey)), "MigrationsBuilderDropForeignKey"), - ReferentialActionType = typeof(ReferentialAction), - ReferentialActionNoAction = (int)ReferentialAction.NoAction, + // ReferentialActionType = typeof(ReferentialAction), + // ReferentialActionNoAction = (int)ReferentialAction.NoAction, - LambdaBase = Resolve(() => typeof(Expression).GetMethod(nameof(Expression.Lambda), 1, BindingFlags.Public | BindingFlags.Static, null, new[] { typeof(Expression), typeof(ParameterExpression[]) }, null), "LambdaBase"), + // LambdaBase = Resolve(() => typeof(Expression).GetMethod(nameof(Expression.Lambda), 1, BindingFlags.Public | BindingFlags.Static, null, new[] { typeof(Expression), typeof(ParameterExpression[]) }, null), "LambdaBase"), - }; - onconfig(o); + //}; + //onconfig(o); + + var o =new DynamicCodeServiceFactory().CreateOptions(onconfig); return new DynamicCodeService(o); } diff --git a/test/EAVFramework.UnitTest/ManifestTests/ManifestTests.cs b/test/EAVFramework.UnitTest/ManifestTests/ManifestTests.cs index 0c3ef4d..c18cf67 100644 --- a/test/EAVFramework.UnitTest/ManifestTests/ManifestTests.cs +++ b/test/EAVFramework.UnitTest/ManifestTests/ManifestTests.cs @@ -1,4 +1,4 @@ -using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -13,6 +13,7 @@ using System.Reflection; using EAVFW.Extensions.Manifest.SDK; using Microsoft.Extensions.Logging.Abstractions; +using System.Text.RegularExpressions; namespace EAVFramework.UnitTest.ManifestTests { @@ -25,8 +26,8 @@ public static void AreEqual(string expected, string actual) var version = typeof(DbContext).Assembly.GetCustomAttribute().InformationalVersion; expected = expected.Replace("{{VERSION}}", version); - - Assert.AreEqual(expected.Trim(), actual.Trim()); + + Assert.AreEqual(Regex.Replace(expected.Trim(), @"\s", string.Empty), Regex.Replace(actual.Trim(), @"\s", string.Empty)); } } diff --git a/test/EAVFramework.UnitTest/UnitTest1.cs b/test/EAVFramework.UnitTest/UnitTest1.cs index a2fedbe..c6986f6 100644 --- a/test/EAVFramework.UnitTest/UnitTest1.cs +++ b/test/EAVFramework.UnitTest/UnitTest1.cs @@ -18,10 +18,11 @@ public class UnitTest1 [TestMethod] - public async Task TestMethod1() + public Task TestMethod1() { var a = new DefaultChoiceEnumBuilder(); Assert.AreEqual("DirectDebitReturnOrRefund", a.GetLiteralName("Direct Debit return/refund")); + return Task.CompletedTask; }