From 93d9cbe03452a93cbb28f8f85366af7d43e5fe8c Mon Sep 17 00:00:00 2001 From: cihandeniz Date: Sat, 30 May 2026 20:08:32 +0300 Subject: [PATCH 01/26] init `migrate-to-order-levels` --- unreleased.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/unreleased.md b/unreleased.md index 5f2ed9319..36382f12e 100644 --- a/unreleased.md +++ b/unreleased.md @@ -3,7 +3,7 @@ ## Features - `Domain` layer now introduces a level system to improve managing convention - execution orders. + execution orders. ## Breaking Changes @@ -38,7 +38,7 @@ ``` - `order: {int}` will now be cast to an `Order` which will fallback to default convention level having (-5000, 4999) range, previous usages like below will - result errors; + result errors; ```csharp // this will throw error conventions.Add(..., order: int.MinValue + 10); @@ -49,4 +49,4 @@ ## Bugfixes -- Adding locate action by conventions was missing claim requirements, fixed \ No newline at end of file +- Adding locate action by conventions was missing claim requirements, fixed From 7bd6f035f168f6d2dffeebba75abfc1e50bddf0f Mon Sep 17 00:00:00 2001 From: cihandeniz Date: Sat, 30 May 2026 22:40:38 +0300 Subject: [PATCH 02/26] migrate to order levels :warning: generate fails --- .../CacheSamplesDomainOverrideFeature.cs | 4 +- .../Domain/ChildDomainOverrideFeature.cs | 7 +- .../CustomAttributeDomainOverrideFeature.cs | 25 ++-- ...WithAssignedGuidIdDomainOverrideFeature.cs | 4 +- ...tityWithAssignedIdDomainOverrideFeature.cs | 4 +- ...ithAutoIncrementIdDomainOverrideFeature.cs | 4 +- .../Domain/FormSampleDomainOverrideFeature.cs | 16 ++- .../Domain/ILocatableDomainOverrideFeature.cs | 4 +- .../Domain/ParentDomainOverrideFeature.cs | 22 ++-- .../ReportPageSampleDomainOverrideFeature.cs | 25 ++-- .../Domain/TestPageDomainOverrideFeature.cs | 25 ++-- core/src/Baked/Architecture/LayerBase.cs | 2 - .../ClaimBasedAuthorizationFeature.cs | 16 ++- .../Baked/Binding/Rest/RestBindingFeature.cs | 25 ++-- .../DomainAssembliesBusinessFeature.cs | 18 ++- .../InMemory/InMemoryCachingFeature.cs | 4 +- .../ScopedMemoryCachingFeature.cs | 4 +- .../AddRemoveChildCodingStyleFeature.cs | 8 +- .../Client/ClientCodingStyleFeature.cs | 8 +- .../CommandPatternCodingStyleFeature.cs | 19 +-- .../EntitySubclassCodingStyleFeature.cs | 16 +-- .../CodingStyle/Id/IdCodingStyleFeature.cs | 2 +- .../InitializableCodingStyleFeature.cs | 15 ++- .../Label/LabelCodingStyleFeature.cs | 3 +- .../LocatableCodingStyleExtensions.cs | 4 +- .../Locatable/LocatableCodingStyleFeature.cs | 11 +- .../LocatableExtensionCodingStyleFeature.cs | 14 +- .../NamespaceAsRouteCodingStyleFeature.cs | 4 +- .../ObjectAsJsonCodingStyleFeature.cs | 6 +- .../Query/QueryCodingStyleFeature.cs | 7 +- .../QueryMethodCodingStyleFeature.cs | 15 ++- .../RecordsAreDtosCodingStyleFeature.cs | 4 +- ...gServicesAreSingletonCodingStyleFeature.cs | 4 +- .../RichEntityCodingStyleFeature.cs | 11 +- .../RichTransientCodingStyleFeature.cs | 11 +- .../ScopedBySuffixCodingStyleFeature.cs | 4 +- .../Unique/UniqueCodingStyleFeature.cs | 3 +- .../UriReturnIsRedirectCodingStyleFeature.cs | 7 +- .../UseBuiltInTypesCodingStyleFeature.cs | 14 +- .../UseNullableTypesCodingStyleFeature.cs | 13 +- .../ValueType/ValueTypeCodingStyleFeature.cs | 4 +- .../Database/MySql/MySqlDatabaseFeature.cs | 3 +- .../Database/Oracle/OracleDatabaseFeature.cs | 3 +- .../PostgreSql/PostgreSqlDatabaseFeature.cs | 3 +- .../Database/Sqlite/SqliteDatabaseFeature.cs | 3 +- .../DomainModelBuilderOptions.cs | 2 +- .../Configuration/DomainModelPostBuilder.cs | 18 +-- .../IAddRemoveAttributeConvention.cs | 6 - .../Configuration/IDomainModelConvention.cs | 5 +- core/src/Baked/Domain/Configuration/Order.cs | 8 +- .../Conventions/AddAttributeConvention.cs | 6 +- .../Conventions/RemoveAttributeConvention.cs | 6 +- .../Conventions/SetAttributeConvention.cs | 6 +- core/src/Baked/Domain/DomainExtensions.cs | 124 ++++++++++-------- core/src/Baked/Monolith/MonolithRecipe.cs | 3 +- .../Baked/Orm/AutoMap/AutoMapOrmFeature.cs | 7 +- .../ConcurrencyRateLimiterFeature.cs | 6 +- core/src/Baked/RestApi/RestApiExtensions.cs | 5 +- core/src/Baked/RestApi/RestApiLayer.cs | 3 - .../Theme/Default/DefaultThemeFeature.cs | 26 ++-- core/src/Baked/Theme/ThemeExtensions.cs | 98 ++++++++------ core/src/Baked/Ui/UiLayer.cs | 3 - .../ActionsAreContentsUxFeature.cs | 9 +- .../ActionsAsButtonsUxFeature.cs | 52 +++++--- .../ActionsAsDataPanelsUxFeature.cs | 13 +- .../DataTableDefaultsUxFeature.cs | 33 +++-- .../DescriptionPropertyUxFeature.cs | 25 ++-- .../EnumParameterIsSelectUxFeature.cs | 17 ++- .../FormInputsAreIftaLabelUxFeature.cs | 4 +- ...alizerParametersAreInPageTitleUxFeature.cs | 10 +- .../LabelsAreFrozenUxFeature.cs | 10 +- .../ListIsDataTableUxFeature.cs | 12 +- .../NumericValuesAreFormattedUxFeature.cs | 13 +- .../ObjectWithListIsDataTableUxFeature.cs | 29 ++-- .../PanelParametersAreStatefulUxFeature.cs | 7 +- .../PropertiesAsFieldsetUxFeature.cs | 20 ++- .../QueryActionAsDataContainerUxFeature.cs | 37 ++++-- .../RoutedTypesAsNavLinksUxFeature.cs | 7 +- .../Baked.Test.Specs/Domain/ManagingOrders.cs | 7 + 79 files changed, 651 insertions(+), 414 deletions(-) delete mode 100644 core/src/Baked/Domain/Configuration/IAddRemoveAttributeConvention.cs diff --git a/core/playground/Baked.Playground.Application/Override/Domain/CacheSamplesDomainOverrideFeature.cs b/core/playground/Baked.Playground.Application/Override/Domain/CacheSamplesDomainOverrideFeature.cs index 487a348e8..08ee25d2b 100644 --- a/core/playground/Baked.Playground.Application/Override/Domain/CacheSamplesDomainOverrideFeature.cs +++ b/core/playground/Baked.Playground.Application/Override/Domain/CacheSamplesDomainOverrideFeature.cs @@ -1,4 +1,5 @@ using Baked.Architecture; +using Baked.Domain.Configuration; using Baked.Playground.Caching; using Baked.Ui; @@ -16,7 +17,8 @@ public void Configure(LayerConfigurator configurator) { tp.Schema.Tabs[0].Contents[0].Narrow = true; tp.Schema.Tabs[0].Contents[1].Narrow = true; - } + }, + order: Order.At.Override ); }); } diff --git a/core/playground/Baked.Playground.Application/Override/Domain/ChildDomainOverrideFeature.cs b/core/playground/Baked.Playground.Application/Override/Domain/ChildDomainOverrideFeature.cs index 8d0a59fc6..5260ac778 100644 --- a/core/playground/Baked.Playground.Application/Override/Domain/ChildDomainOverrideFeature.cs +++ b/core/playground/Baked.Playground.Application/Override/Domain/ChildDomainOverrideFeature.cs @@ -1,6 +1,6 @@ using Baked.Architecture; +using Baked.Domain.Configuration; using Baked.Playground.Orm; -using Baked.RestApi; using Baked.Theme.Default; namespace Baked.Playground.Override.Domain; @@ -15,12 +15,13 @@ public void Configure(LayerConfigurator configurator) conventions.AddPropertyAttributeConfiguration( when: c => c.Type.Is() && c.Property.PropertyType.Is() || c.Property.PropertyType.Is(), - attribute: data => data.Visible = false + attribute: data => data.Visible = false, + order: Order.At.Override ); conventions.RemoveMethodAttribute( when: c => c.Type.Is(), - order: RestApiLayer.MaxConventionOrder + 15 + order: Order.At.Override ); }); } diff --git a/core/playground/Baked.Playground.Application/Override/Domain/CustomAttributeDomainOverrideFeature.cs b/core/playground/Baked.Playground.Application/Override/Domain/CustomAttributeDomainOverrideFeature.cs index 638e38bef..8c6083b9d 100644 --- a/core/playground/Baked.Playground.Application/Override/Domain/CustomAttributeDomainOverrideFeature.cs +++ b/core/playground/Baked.Playground.Application/Override/Domain/CustomAttributeDomainOverrideFeature.cs @@ -1,4 +1,5 @@ using Baked.Architecture; +using Baked.Domain.Configuration; using Baked.Playground.Business; namespace Baked.Playground.Override.Domain; @@ -11,37 +12,43 @@ public void Configure(LayerConfigurator configurator) { conventions.SetTypeAttribute( attribute: () => new CustomAttribute(), - when: c => c.Type.Is() + when: c => c.Type.Is(), + order: Order.At.Override ); conventions.AddTypeAttributeConfiguration( attribute: attr => attr.Value = "FROM CONVENTION", - when: c => c.Type.Is() + when: c => c.Type.Is(), + order: Order.At.Override ); conventions.SetPropertyAttribute( attribute: () => new CustomAttribute(), when: c => c.Type.Is() && - c.Property.Name == nameof(Record.Text) + c.Property.Name == nameof(Record.Text), + order: Order.At.Override ); conventions.AddPropertyAttributeConfiguration( attribute: attr => attr.Value = "FROM CONVENTION", when: c => c.Type.Is() && - c.Property.Name == nameof(Record.Text) + c.Property.Name == nameof(Record.Text), + order: Order.At.Override ); conventions.SetMethodAttribute( attribute: () => new CustomAttribute(), when: c => c.Type.Is() && - c.Method.Name == nameof(Class.Method) + c.Method.Name == nameof(Class.Method), + order: Order.At.Override ); conventions.AddMethodAttributeConfiguration( attribute: attr => attr.Value = "FROM CONVENTION", when: c => c.Type.Is() && - c.Method.Name == nameof(Class.Method) + c.Method.Name == nameof(Class.Method), + order: Order.At.Override ); conventions.SetParameterAttribute( @@ -49,14 +56,16 @@ public void Configure(LayerConfigurator configurator) when: c => c.Type.Is() && c.Method.Name == nameof(MethodSamples.PrimitiveParameters) && - c.Parameter.Name == "string" + c.Parameter.Name == "string", + order: Order.At.Override ); conventions.AddParameterAttributeConfiguration( attribute: attr => attr.Value = "FROM CONVENTION", when: c => c.Type.Is() && c.Method.Name == nameof(MethodSamples.PrimitiveParameters) && - c.Parameter.Name == "string" + c.Parameter.Name == "string", + order: Order.At.Override ); }); } diff --git a/core/playground/Baked.Playground.Application/Override/Domain/EntityWithAssignedGuidIdDomainOverrideFeature.cs b/core/playground/Baked.Playground.Application/Override/Domain/EntityWithAssignedGuidIdDomainOverrideFeature.cs index 43417c0d6..85b8e9d74 100644 --- a/core/playground/Baked.Playground.Application/Override/Domain/EntityWithAssignedGuidIdDomainOverrideFeature.cs +++ b/core/playground/Baked.Playground.Application/Override/Domain/EntityWithAssignedGuidIdDomainOverrideFeature.cs @@ -1,5 +1,6 @@ using Baked.Architecture; using Baked.Business; +using Baked.Domain.Configuration; using Baked.Playground.CodingStyle.Id; namespace Baked.Playground.Override.Domain; @@ -12,7 +13,8 @@ public void Configure(LayerConfigurator configurator) { conventions.AddPropertyAttributeConfiguration( when: c => c.Type.Is(), - attribute: id => id.AssignedGuid() + attribute: id => id.AssignedGuid(), + order: Order.At.Override ); }); } diff --git a/core/playground/Baked.Playground.Application/Override/Domain/EntityWithAssignedIdDomainOverrideFeature.cs b/core/playground/Baked.Playground.Application/Override/Domain/EntityWithAssignedIdDomainOverrideFeature.cs index f6d274b11..38dc9fe74 100644 --- a/core/playground/Baked.Playground.Application/Override/Domain/EntityWithAssignedIdDomainOverrideFeature.cs +++ b/core/playground/Baked.Playground.Application/Override/Domain/EntityWithAssignedIdDomainOverrideFeature.cs @@ -1,5 +1,6 @@ using Baked.Architecture; using Baked.Business; +using Baked.Domain.Configuration; using Baked.Playground.CodingStyle.Id; namespace Baked.Playground.Override.Domain; @@ -12,7 +13,8 @@ public void Configure(LayerConfigurator configurator) { conventions.AddPropertyAttributeConfiguration( when: c => c.Type.Is(), - attribute: id => id.Assigned() + attribute: id => id.Assigned(), + order: Order.At.Override ); }); } diff --git a/core/playground/Baked.Playground.Application/Override/Domain/EntityWithAutoIncrementIdDomainOverrideFeature.cs b/core/playground/Baked.Playground.Application/Override/Domain/EntityWithAutoIncrementIdDomainOverrideFeature.cs index 136c60bf6..34419b1ba 100644 --- a/core/playground/Baked.Playground.Application/Override/Domain/EntityWithAutoIncrementIdDomainOverrideFeature.cs +++ b/core/playground/Baked.Playground.Application/Override/Domain/EntityWithAutoIncrementIdDomainOverrideFeature.cs @@ -1,5 +1,6 @@ using Baked.Architecture; using Baked.Business; +using Baked.Domain.Configuration; using Baked.Playground.CodingStyle.Id; namespace Baked.Playground.Override.Domain; @@ -12,7 +13,8 @@ public void Configure(LayerConfigurator configurator) { conventions.AddPropertyAttributeConfiguration( when: c => c.Type.Is(), - attribute: id => id.AutoIncrement() + attribute: id => id.AutoIncrement(), + order: Order.At.Override ); }); } diff --git a/core/playground/Baked.Playground.Application/Override/Domain/FormSampleDomainOverrideFeature.cs b/core/playground/Baked.Playground.Application/Override/Domain/FormSampleDomainOverrideFeature.cs index 5d7511533..8bfdc0230 100644 --- a/core/playground/Baked.Playground.Application/Override/Domain/FormSampleDomainOverrideFeature.cs +++ b/core/playground/Baked.Playground.Application/Override/Domain/FormSampleDomainOverrideFeature.cs @@ -1,5 +1,6 @@ using Baked.Architecture; using Baked.Business; +using Baked.Domain.Configuration; using Baked.Playground.Orm; using Baked.Playground.Theme; using Baked.Theme; @@ -18,17 +19,20 @@ public void Configure(LayerConfigurator configurator) { conventions.AddMethodAttributeConfiguration( when: c => c.Type.Is() && c.Method.Name == nameof(FormSample.NewParent), - attribute: (a, c) => a.RoutePathBack = "/form-sample" + attribute: (a, c) => a.RoutePathBack = "/form-sample", + order: Order.At.Override ); conventions.AddMethodAttributeConfiguration( when: c => c.Type.Is() && c.Method.Name.Contains("Child"), - attribute: a => a.HideInLists = true + attribute: a => a.HideInLists = true, + order: Order.At.Override ); conventions.SetMethodAttribute( when: c => c.Type.Is() && c.Method.Name == nameof(FormSample.GetParents), - attribute: () => new QueryMethodAttribute() + attribute: () => new QueryMethodAttribute(), + order: Order.At.Override ); conventions.AddMethodComponentConfiguration( @@ -37,14 +41,16 @@ public void Configure(LayerConfigurator configurator) { fp.Schema.ForEachInputGroup(g => g.Wide = true); fp.Schema.Sections[0].InputGroups.Move("name", toTop: true); - } + }, + order: Order.At.Override ); // Properties conventions.AddPropertyComponent( when: c => c.Property.PropertyType.SkipNullable().IsEnum, where: cc => cc.Path.StartsWith(nameof(Page), nameof(FormSample)), - component: () => B.Text() + component: () => B.Text(), + order: Order.At.Override ); }); } diff --git a/core/playground/Baked.Playground.Application/Override/Domain/ILocatableDomainOverrideFeature.cs b/core/playground/Baked.Playground.Application/Override/Domain/ILocatableDomainOverrideFeature.cs index 2cb61c77c..8ca323aef 100644 --- a/core/playground/Baked.Playground.Application/Override/Domain/ILocatableDomainOverrideFeature.cs +++ b/core/playground/Baked.Playground.Application/Override/Domain/ILocatableDomainOverrideFeature.cs @@ -1,5 +1,6 @@ using Baked.Architecture; using Baked.Business; +using Baked.Domain.Configuration; using Baked.Playground.CodingStyle.Locatable; namespace Baked.Playground.Override.Domain; @@ -12,7 +13,8 @@ public void Configure(LayerConfigurator configurator) { conventions.SetTypeAttribute( when: c => c.Type.Is(), - attribute: () => new LocatableAttribute() + attribute: () => new LocatableAttribute(), + order: Order.At.Override ); }); } diff --git a/core/playground/Baked.Playground.Application/Override/Domain/ParentDomainOverrideFeature.cs b/core/playground/Baked.Playground.Application/Override/Domain/ParentDomainOverrideFeature.cs index 41afe338d..b145afaa3 100644 --- a/core/playground/Baked.Playground.Application/Override/Domain/ParentDomainOverrideFeature.cs +++ b/core/playground/Baked.Playground.Application/Override/Domain/ParentDomainOverrideFeature.cs @@ -1,7 +1,7 @@ using Baked.Architecture; using Baked.Business; +using Baked.Domain.Configuration; using Baked.Playground.Orm; -using Baked.RestApi; using Baked.RestApi.Model; using Baked.Theme.Default; using Baked.Ui; @@ -20,12 +20,13 @@ public void Configure(LayerConfigurator configurator) conventions.SetPropertyAttribute( when: c => c.Type.Is() && c.Property.Name == nameof(Parent.Surname), - attribute: () => new LabelAttribute() + attribute: () => new LabelAttribute(), + order: Order.At.Override ); conventions.RemoveMethodAttribute( when: c => c.Type.Is() && c.Method.Name == nameof(Parent.RemoveChild), - order: RestApiLayer.MaxConventionOrder + 15 + order: Order.At.Override ); // Move `AddChild` action to contents @@ -38,7 +39,8 @@ public void Configure(LayerConfigurator configurator) var addChildRoute = addChild.Get().GetRoute(); pt.Schema.Actions.RemoveAll(a => a.Action is RemoteAction ra && ra.Path == addChildRoute); - } + }, + order: Order.At.Override ); conventions.AddTypeComponentConfiguration( @@ -50,23 +52,27 @@ public void Configure(LayerConfigurator configurator) dp.Schema.Contents.Add( addChild.GenerateRequiredSchema(cc.Drill(nameof(SimplePage), nameof(SimplePage.Contents))) ); - } + }, + order: Order.At.Override ); } conventions.AddMethodSchemaConfiguration( when: c => c.Type.Is() && c.Method.Name == nameof(Parent.AddChild), - schema: s => s.Side = true + schema: s => s.Side = true, + order: Order.At.Override ); conventions.AddTypeComponentConfiguration
( when: c => c.Type.Is(), - component: dt => dt.ReloadOn(nameof(Parent.Update).Kebaberize()) + component: dt => dt.ReloadOn(nameof(Parent.Update).Kebaberize()), + order: Order.At.Override ); conventions.AddMethodComponentConfiguration( when: c => c.Type.Is() && c.Method.Name == nameof(Parent.GetChildren), - component: dt => dt.ReloadOn(nameof(Parent.AddChild).Kebaberize()) + component: dt => dt.ReloadOn(nameof(Parent.AddChild).Kebaberize()), + order: Order.At.Override ); }); } diff --git a/core/playground/Baked.Playground.Application/Override/Domain/ReportPageSampleDomainOverrideFeature.cs b/core/playground/Baked.Playground.Application/Override/Domain/ReportPageSampleDomainOverrideFeature.cs index 692ed24c2..4d33944b3 100644 --- a/core/playground/Baked.Playground.Application/Override/Domain/ReportPageSampleDomainOverrideFeature.cs +++ b/core/playground/Baked.Playground.Application/Override/Domain/ReportPageSampleDomainOverrideFeature.cs @@ -1,5 +1,6 @@ using Baked.Architecture; using Baked.Business; +using Baked.Domain.Configuration; using Baked.Playground.Theme; using Baked.Ui; @@ -19,37 +20,44 @@ public void Configure(LayerConfigurator configurator) // Tabs conventions.AddMethodAttributeConfiguration( when: c => c.Type.Is() && c.Method.DefaultOverload.ReturnType.SkipTask().Is(), - attribute: group => group.TabName = "SingleValue" + attribute: group => group.TabName = "SingleValue", + order: Order.At.Override ); conventions.AddMethodAttributeConfiguration( when: c => c.Type.Is() && c.Method.DefaultOverload.ReturnsList(), - attribute: group => group.TabName = "DataTable" + attribute: group => group.TabName = "DataTable", + order: Order.At.Override ); conventions.AddTypeComponent( when: c => c.Type.Is(), where: cc => cc.Path.EndsWith("SingleValue", nameof(Tab.Icon)), - component: () => B.Icon("pi-box") + component: () => B.Icon("pi-box"), + order: Order.At.Override ); conventions.AddTypeComponent( when: c => c.Type.Is(), where: cc => cc.Path.EndsWith("DataTable", nameof(Tab.Icon)), - component: () => B.Icon("pi-table") + component: () => B.Icon("pi-table"), + order: Order.At.Override ); // Allowing admin token for report api conventions.AddMethodSchemaConfiguration( when: c => c.Type.Is(), - schema: rd => rd.Headers = Inline(new { Authorization = "token-admin-ui" }) + schema: rd => rd.Headers = Inline(new { Authorization = "token-admin-ui" }), + order: Order.At.Override ); // Parameter overrides conventions.AddParameterComponent( when: c => c.Type.Is() && c.Method.Name == nameof(ReportPageSample.With) && !c.Parameter.IsNullable, - component: (c, cc) => ParameterSelect(c.Parameter, cc) + component: (c, cc) => ParameterSelect(c.Parameter, cc), + order: Order.At.Override ); conventions.AddParameterComponent( when: c => c.Type.Is() && c.Method.Name == nameof(ReportPageSample.GetFirst) && c.Parameter.Name == "count", - component: (c, cc) => ParameterSelect(c.Parameter, cc) + component: (c, cc) => ParameterSelect(c.Parameter, cc), + order: Order.At.Override ); // Page overrides @@ -63,7 +71,8 @@ public void Configure(LayerConfigurator configurator) tp.Schema.Tabs[0].Contents[1].Component.Schema.As().Collapsed = true; tp.Schema.Tabs[0].Contents[2].Component.Schema.As().Collapsed = true; tp.Schema.Tabs[1].Contents[1].Component.Schema.As().Collapsed = true; - } + }, + order: Order.At.Override ); }); } diff --git a/core/playground/Baked.Playground.Application/Override/Domain/TestPageDomainOverrideFeature.cs b/core/playground/Baked.Playground.Application/Override/Domain/TestPageDomainOverrideFeature.cs index 92d3ad76e..641bb37d9 100644 --- a/core/playground/Baked.Playground.Application/Override/Domain/TestPageDomainOverrideFeature.cs +++ b/core/playground/Baked.Playground.Application/Override/Domain/TestPageDomainOverrideFeature.cs @@ -1,4 +1,5 @@ using Baked.Architecture; +using Baked.Domain.Configuration; using Baked.Playground.Theme; using Baked.Theme; using Baked.Ui; @@ -19,18 +20,21 @@ public void Configure(LayerConfigurator configurator) conventions.AddTypeComponent( when: c => c.Type.Is(), where: cc => cc.Path.EndsWith(nameof(Page)), - component: () => B.TabbedPage("test-page", B.PageTitle("Test Page")) + component: () => B.TabbedPage("test-page", B.PageTitle("Test Page")), + order: Order.At.Override ); conventions.AddTypeComponentConfiguration( when: c => c.Type.Is(), component: (tp, c, cc) => tp.Schema.Tabs.AddRange( c.Type.GenerateSchemas(cc.Drill(nameof(TabbedPage.Tabs))) - ) + ), + order: Order.At.Override ); conventions.AddTypeSchema( when: c => c.Type.Is(), where: cc => cc.Path.EndsWith(nameof(TabbedPage.Tabs)), - schema: (c, cc) => B.Tab("default") + schema: (c, cc) => B.Tab("default"), + order: Order.At.Override ); conventions.AddTypeSchemaConfiguration( when: c => c.Type.Is(), @@ -38,26 +42,31 @@ public void Configure(LayerConfigurator configurator) c.Type .GetMethod(nameof(TestPage.GetData)) .GenerateRequiredSchema(cc.Drill(t.Id, nameof(Tab.Contents), 0)) - ) + ), + order: Order.At.Override ); conventions.AddMethodSchema( when: c => c.Type.Is() && c.Method.Name == nameof(TestPage.GetData), where: cc => cc.Path.EndsWith(nameof(Tab.Contents), 0), - schema: (c, cc) => B.Content(component: c.Method.GenerateRequiredComponent(cc.Drill(nameof(Content.Component))), c.Method.Name.Kebaberize()) + schema: (c, cc) => B.Content(component: c.Method.GenerateRequiredComponent(cc.Drill(nameof(Content.Component))), c.Method.Name.Kebaberize()), + order: Order.At.Override ); conventions.AddMethodSchemaConfiguration( when: c => c.Type.Is() && c.Method.Name == nameof(TestPage.GetData), - schema: tabContent => tabContent.Narrow = true + schema: tabContent => tabContent.Narrow = true, + order: Order.At.Override ); conventions.AddMethodComponent( when: c => c.Type.Is() && c.Method.Name == nameof(TestPage.GetData), where: cc => cc.Path.EndsWith(nameof(Content.Component)), - component: (c, cc) => MethodText(c.Method, cc) + component: (c, cc) => MethodText(c.Method, cc), + order: Order.At.Override ); conventions.AddMethodComponentConfiguration( when: c => c.Type.Is() && c.Method.Name == nameof(TestPage.GetData), - component: t => t.Schema.MaxLength = 20 + component: t => t.Schema.MaxLength = 20, + order: Order.At.Override ); }); } diff --git a/core/src/Baked/Architecture/LayerBase.cs b/core/src/Baked/Architecture/LayerBase.cs index 4fb44e40f..8c1f8c76b 100644 --- a/core/src/Baked/Architecture/LayerBase.cs +++ b/core/src/Baked/Architecture/LayerBase.cs @@ -2,8 +2,6 @@ public abstract class LayerBase : ILayer { - public const int ConventionOrderLimit = 1000; - protected ApplicationContext Context { get; private set; } = default!; protected virtual string Id => GetType().Name; diff --git a/core/src/Baked/Authorization/ClaimBased/ClaimBasedAuthorizationFeature.cs b/core/src/Baked/Authorization/ClaimBased/ClaimBasedAuthorizationFeature.cs index 350c6010a..9e74ff24e 100644 --- a/core/src/Baked/Authorization/ClaimBased/ClaimBasedAuthorizationFeature.cs +++ b/core/src/Baked/Authorization/ClaimBased/ClaimBasedAuthorizationFeature.cs @@ -1,5 +1,5 @@ using Baked.Architecture; -using Baked.RestApi; +using Baked.Domain.Configuration; using Baked.RestApi.Model; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Builder; @@ -16,17 +16,19 @@ public void Configure(LayerConfigurator configurator) { conventions.SetMethodAttribute( when: c => !c.Method.Has() && c.Type.Has(), - attribute: c => c.Type.Get() + attribute: c => c.Type.Get(), + order: Order.At.Infra ); conventions.SetMethodAttribute( when: c => !c.Method.Has() && c.Type.Has(), - attribute: c => c.Type.Get() + attribute: c => c.Type.Get(), + order: Order.At.Infra ); - conventions.Add(new AllowAnonymousIsAllowAnonymousConvention(), order: RestApiLayer.MaxConventionOrder - 10); - conventions.Add(new RequireUserIsAuthorizeConvention(), order: RestApiLayer.MaxConventionOrder - 10); - conventions.Add(new AddBaseClaimsAsAuthorizePolicyConvention(_baseClaims), order: RestApiLayer.MaxConventionOrder - 10); - conventions.Add(new AddRequireUserClaimsAsAuthorizePolicyConvention(), order: RestApiLayer.MaxConventionOrder - 10); + conventions.Add(new AllowAnonymousIsAllowAnonymousConvention(), order: Order.At.Max); + conventions.Add(new RequireUserIsAuthorizeConvention(), order: Order.At.Max); + conventions.Add(new AddBaseClaimsAsAuthorizePolicyConvention(_baseClaims), order: Order.At.Max); + conventions.Add(new AddRequireUserClaimsAsAuthorizePolicyConvention(), order: Order.At.Max); }); configurator.Domain.ConfigureExportConfigurations(exports => diff --git a/core/src/Baked/Binding/Rest/RestBindingFeature.cs b/core/src/Baked/Binding/Rest/RestBindingFeature.cs index 3083ac9e4..ede13b29e 100644 --- a/core/src/Baked/Binding/Rest/RestBindingFeature.cs +++ b/core/src/Baked/Binding/Rest/RestBindingFeature.cs @@ -38,7 +38,7 @@ public void Configure(LayerConfigurator configurator) !c.Type.IsGenericType && c.Type.TryGetMembers(out var members) && members.Methods.Any(m => m.DefaultOverload.IsPublicInstanceWithNoSpecialName), - order: 10 + order: Order.At.Infra + 10 ); conventions.SetMethodAttribute( attribute: c => new ActionModelAttribute(), @@ -47,12 +47,12 @@ public void Configure(LayerConfigurator configurator) !c.Method.Has() && c.Method.DefaultOverload.IsPublicInstanceWithNoSpecialName && c.Method.DefaultOverload.AllParametersAreApiInput(), - order: RestApiLayer.MaxConventionOrder + order: Order.At.AbsoluteMax // TODO consider using Max ); conventions.SetParameterAttribute( attribute: c => new ParameterModelAttribute(), when: c => c.Parameter.IsApiInput, - order: RestApiLayer.MaxConventionOrder + order: Order.At.AbsoluteMax // TODO consider using Max ); // init before any domain convention @@ -70,24 +70,25 @@ public void Configure(LayerConfigurator configurator) (Regexes.IsUpdateChangeOrSet, HttpMethod.Put), (Regexes.StartsWithUpdateChangeOrSet, HttpMethod.Patch), (Regexes.StartsWithDeleteRemoveOrClear, HttpMethod.Delete) - ])); - conventions.Add(new GetAndDeleteAcceptsOnlyQueryConvention()); - conventions.Add(new RemoveFromRouteConvention(["Get"])); - conventions.Add(new RemoveFromRouteConvention(["Update", "Change", "Set"])); - conventions.Add(new RemoveFromRouteConvention(["Delete", "Remove", "Clear"])); + ]), order: Order.At.Infra); + conventions.Add(new GetAndDeleteAcceptsOnlyQueryConvention(), order: Order.At.Infra); + conventions.Add(new RemoveFromRouteConvention(["Get"]), order: Order.At.Infra); + conventions.Add(new RemoveFromRouteConvention(["Update", "Change", "Set"]), order: Order.At.Infra); + conventions.Add(new RemoveFromRouteConvention(["Delete", "Remove", "Clear"]), order: Order.At.Infra); conventions.AddMethodAttributeConfiguration( attribute: action => action.AdditionalAttributes.Add("Consumes(\"application/json\")"), when: (_, action) => action.HasBody, - order: 10 + order: Order.At.Infra + 10 ); conventions.AddMethodAttributeConfiguration( attribute: action => action.AdditionalAttributes.Add("Produces(\"application/json\")"), when: (_, action) => !action.ReturnIsVoid, - order: 10 + order: Order.At.Infra + 10 ); - conventions.Add(new UseDocumentationAsDescriptionConvention(_tagDescriptions, _examples), order: 10); + conventions.Add(new UseDocumentationAsDescriptionConvention(_tagDescriptions, _examples), order: Order.At.Infra + 10); conventions.AddMethodAttributeConfiguration((action, context) => - action.AdditionalAttributes.Add($"{typeof(MappedMethodAttribute).FullName}(\"{context.Type.FullName}\", \"{context.Method.Name}\")") + action.AdditionalAttributes.Add($"{typeof(MappedMethodAttribute).FullName}(\"{context.Type.FullName}\", \"{context.Method.Name}\")"), + order: Order.At.Infra ); }); diff --git a/core/src/Baked/Business/DomainAssemblies/DomainAssembliesBusinessFeature.cs b/core/src/Baked/Business/DomainAssemblies/DomainAssembliesBusinessFeature.cs index 9f2af5468..7c4e993df 100644 --- a/core/src/Baked/Business/DomainAssemblies/DomainAssembliesBusinessFeature.cs +++ b/core/src/Baked/Business/DomainAssemblies/DomainAssembliesBusinessFeature.cs @@ -61,6 +61,9 @@ public void Configure(LayerConfigurator configurator) builder.BuildLevels.Add(context => context.Type.IsGenericType && context.DomainTypesContain(context.Type.GetGenericTypeDefinition()), BuildLevels.Members); builder.BuildLevels.Add(BuildLevels.Metadata); + builder.ConventionLevels.Insert(0, "Infra"); + builder.ConventionLevels.Add("Override"); + builder.Index.Type.Add(); builder.Index.Type.Add(); builder.Index.Type.Add(); @@ -108,7 +111,8 @@ public void Configure(LayerConfigurator configurator) return new NamespaceAttribute(@namespace); }, - when: c => setNamespaceWhen(c.Type) + when: c => setNamespaceWhen(c.Type), + order: Order.At.Infra ); conventions.SetTypeAttribute( attribute: () => new ServiceAttribute(), @@ -120,7 +124,8 @@ public void Configure(LayerConfigurator configurator) !c.Type.IsGenericTypeDefinition && !c.Type.IsAssignableTo() && c.Type.TryGetMembers(out var members) && - !members.Methods.Contains("$") // if type is record + !members.Methods.Contains("$"), // if type is record + order: Order.At.Infra ); conventions.SetMethodAttribute( @@ -128,7 +133,8 @@ public void Configure(LayerConfigurator configurator) when: c => c.Method.DefaultOverload.DeclaringType is not null && c.Method.DefaultOverload.DeclaringType.TryGetMetadata(out var metadata) && - !metadata.Has() + !metadata.Has(), + order: Order.At.Infra ); conventions.SetMethodAttribute( @@ -137,12 +143,14 @@ c.Method.DefaultOverload.DeclaringType is not null && c.Method.DefaultOverload.BaseDefinition is not null && c.Method.DefaultOverload.BaseDefinition.DeclaringType is not null && c.Method.DefaultOverload.BaseDefinition.DeclaringType.TryGetMetadata(out var metadata) && - !metadata.Has() + !metadata.Has(), + order: Order.At.Infra ); conventions.SetTypeAttribute( attribute: () => new CasterAttribute(), - when: c => c.Type.IsClass && !c.Type.IsAbstract && c.Type.IsAssignableTo(typeof(ICasts<,>)) + when: c => c.Type.IsClass && !c.Type.IsAbstract && c.Type.IsAssignableTo(typeof(ICasts<,>)), + order: Order.At.Infra ); }); diff --git a/core/src/Baked/Caching/InMemory/InMemoryCachingFeature.cs b/core/src/Baked/Caching/InMemory/InMemoryCachingFeature.cs index 6668cf3cc..a8f5102a3 100644 --- a/core/src/Baked/Caching/InMemory/InMemoryCachingFeature.cs +++ b/core/src/Baked/Caching/InMemory/InMemoryCachingFeature.cs @@ -1,4 +1,5 @@ using Baked.Architecture; +using Baked.Domain.Configuration; using Baked.Runtime; using Baked.Ui; using Microsoft.Extensions.Caching.Memory; @@ -15,7 +16,8 @@ public void Configure(LayerConfigurator configurator) { conventions.AddMethodSchemaConfiguration( schema: rd => rd.SetAttribute("client-cache", "application"), - when: c => c.Method.TryGet(out var clientCache) && clientCache.Type == "application" + when: c => c.Method.TryGet(out var clientCache) && clientCache.Type == "application", + order: Order.At.Infra ); }); diff --git a/core/src/Baked/Caching/ScopedMemory/ScopedMemoryCachingFeature.cs b/core/src/Baked/Caching/ScopedMemory/ScopedMemoryCachingFeature.cs index 8513a238a..5509664e7 100644 --- a/core/src/Baked/Caching/ScopedMemory/ScopedMemoryCachingFeature.cs +++ b/core/src/Baked/Caching/ScopedMemory/ScopedMemoryCachingFeature.cs @@ -1,4 +1,5 @@ using Baked.Architecture; +using Baked.Domain.Configuration; using Baked.Runtime; using Baked.Ui; using Microsoft.Extensions.Caching.Memory; @@ -15,7 +16,8 @@ public void Configure(LayerConfigurator configurator) { conventions.AddMethodSchemaConfiguration( schema: rd => rd.SetAttribute("client-cache", "user"), - when: c => c.Method.TryGet(out var clientCache) && clientCache.Type == "user" + when: c => c.Method.TryGet(out var clientCache) && clientCache.Type == "user", + order: Order.At.Infra ); }); diff --git a/core/src/Baked/CodingStyle/AddRemoveChild/AddRemoveChildCodingStyleFeature.cs b/core/src/Baked/CodingStyle/AddRemoveChild/AddRemoveChildCodingStyleFeature.cs index d4082cb77..d41a6cfea 100644 --- a/core/src/Baked/CodingStyle/AddRemoveChild/AddRemoveChildCodingStyleFeature.cs +++ b/core/src/Baked/CodingStyle/AddRemoveChild/AddRemoveChildCodingStyleFeature.cs @@ -1,4 +1,5 @@ using Baked.Architecture; +using Baked.Domain.Configuration; using Baked.RestApi; using Baked.RestApi.Conventions; using Baked.RestApi.Model; @@ -21,10 +22,11 @@ public void Configure(LayerConfigurator configurator) }, when: (_, action) => (action.Method == HttpMethod.Delete && action.RouteParts.Count >= 2) || - (action.Method == HttpMethod.Post && Regexes.StartsWithAddCreateOrNew.IsMatch(action.Name) && action.RouteParts.Count >= 2) + (action.Method == HttpMethod.Post && Regexes.StartsWithAddCreateOrNew.IsMatch(action.Name) && action.RouteParts.Count >= 2), + order: Order.At.Infra ); - conventions.Add(new OnlyLocatableParameterIsInRouteForDeleteChildConvention()); - conventions.Add(new RemoveFromRouteConvention(["Add", "Create", "New"])); + conventions.Add(new OnlyLocatableParameterIsInRouteForDeleteChildConvention(), order: Order.At.Infra); + conventions.Add(new RemoveFromRouteConvention(["Add", "Create", "New"]), order: Order.At.Infra); }); } } \ No newline at end of file diff --git a/core/src/Baked/CodingStyle/Client/ClientCodingStyleFeature.cs b/core/src/Baked/CodingStyle/Client/ClientCodingStyleFeature.cs index 3165a8d57..69bf4607c 100644 --- a/core/src/Baked/CodingStyle/Client/ClientCodingStyleFeature.cs +++ b/core/src/Baked/CodingStyle/Client/ClientCodingStyleFeature.cs @@ -1,5 +1,5 @@ using Baked.Architecture; -using Baked.RestApi; +using Baked.Domain.Configuration; using Baked.RestApi.Model; namespace Baked.CodingStyle.Client; @@ -17,11 +17,13 @@ public void Configure(LayerConfigurator configurator) { conventions.SetTypeAttribute( when: c => c.Type.IsInterface && c.Type.Name.EndsWith("Client"), - attribute: () => new ClientAttribute() + attribute: () => new ClientAttribute(), + order: Order.At.Infra ); + conventions.RemoveTypeAttribute( when: c => c.Type.Name.EndsWith("Client"), - order: RestApiLayer.MaxConventionOrder - 10 + order: Order.At.Max - 10 ); }); diff --git a/core/src/Baked/CodingStyle/CommandPattern/CommandPatternCodingStyleFeature.cs b/core/src/Baked/CodingStyle/CommandPattern/CommandPatternCodingStyleFeature.cs index 4bb11fe6a..8f7e2fa64 100644 --- a/core/src/Baked/CodingStyle/CommandPattern/CommandPatternCodingStyleFeature.cs +++ b/core/src/Baked/CodingStyle/CommandPattern/CommandPatternCodingStyleFeature.cs @@ -1,6 +1,7 @@ using Baked.Architecture; using Baked.Binding; using Baked.Business; +using Baked.Domain.Configuration; using Baked.Lifetime; using Baked.RestApi.Conventions; using Baked.RestApi.Model; @@ -26,31 +27,31 @@ public void Configure(LayerConfigurator configurator) m.DefaultOverload.AllParametersAreApiInput() && m.DefaultOverload.IsPublicInstanceWithNoSpecialName ), - order: 40 + order: Order.At.Infra + 40 ); conventions.RemoveTypeAttribute( when: c => c.Type.Has() && !c.Type.Has() && !c.Type.Has(), - order: 40 + order: Order.At.Infra + 40 ); - conventions.Add(new IncludeClassDocsForActionNamesConvention(_methodNames), order: -10); - conventions.Add(new UseClassNameInsteadOfActionNamesConvention(_methodNames), order: -10); - conventions.Add(new RemoveFromRouteConvention(_methodNames)); - conventions.Add(new RemoveFromRouteConvention(["Sync", "Create"])); - conventions.Add(new UseRootPathAsGroupNameForSingleMethodNonLocatablesConvention()); + conventions.Add(new IncludeClassDocsForActionNamesConvention(_methodNames), order: Order.At.Infra - 10); + conventions.Add(new UseClassNameInsteadOfActionNamesConvention(_methodNames), order: Order.At.Infra - 10); + conventions.Add(new RemoveFromRouteConvention(_methodNames), order: Order.At.Infra); + conventions.Add(new RemoveFromRouteConvention(["Sync", "Create"]), order: Order.At.Infra); + conventions.Add(new UseRootPathAsGroupNameForSingleMethodNonLocatablesConvention(), order: Order.At.Infra); conventions.Add(new NoRequestBodyForSingleEnumerableParametersConvention( _when: action => action.Name.StartsWith("Sync"), _method: HttpMethod.Put - ), order: -10); + ), order: Order.At.Infra - 10); conventions.Add(new NoRequestBodyForSingleEnumerableParametersConvention( _when: action => action.Name.StartsWith("Create"), _method: HttpMethod.Patch - ), order: -10); + ), order: Order.At.Infra - 10); }); configurator.RestApi.ConfigureSwaggerGenOptions(swaggerGenOptions => diff --git a/core/src/Baked/CodingStyle/EntitySubclass/EntitySubclassCodingStyleFeature.cs b/core/src/Baked/CodingStyle/EntitySubclass/EntitySubclassCodingStyleFeature.cs index a4aa5fee1..e6c120699 100644 --- a/core/src/Baked/CodingStyle/EntitySubclass/EntitySubclassCodingStyleFeature.cs +++ b/core/src/Baked/CodingStyle/EntitySubclass/EntitySubclassCodingStyleFeature.cs @@ -1,7 +1,7 @@ using Baked.Architecture; using Baked.Business; +using Baked.Domain.Configuration; using Baked.Orm; -using Baked.RestApi; using Baked.RestApi.Model; namespace Baked.CodingStyle.EntitySubclass; @@ -32,7 +32,7 @@ public void Configure(LayerConfigurator configurator) return entityType.Apply(t => new EntitySubclassAttribute(t, c.Type.Name.Replace(t.Name, string.Empty))); }, - order: 10 + order: Order.At.Infra + 10 ); conventions.SetTypeAttribute( when: c => c.Type.Has(), @@ -54,20 +54,20 @@ public void Configure(LayerConfigurator configurator) set(c.Type, new LocatableAttribute()); }, - order: 40 + order: Order.At.Infra + 40 ); conventions.SetMethodAttribute( attribute: c => new ActionModelAttribute(), when: c => c.Type.Has() && c.Method.Has() && c.Method.Overloads.Any(o => o.IsPublic && !o.IsStatic && !o.IsSpecialName && o.AllParametersAreApiInput()), - order: 30 + order: Order.At.Infra + 30 ); - conventions.Add(new UniqueIdParameterConvention(), order: RestApiLayer.MaxConventionOrder - 20); - conventions.Add(new EntitySubclassUnderEntitiesConvention(), order: RestApiLayer.MaxConventionOrder); - conventions.Add(new EntitySubclassInitializerIsPostResourceConvention(), order: RestApiLayer.MaxConventionOrder); - conventions.Add(new AddSubclassNameToRouteConvention(), order: RestApiLayer.MaxConventionOrder); + conventions.Add(new UniqueIdParameterConvention(), order: Order.At.Max - 20); + conventions.Add(new EntitySubclassUnderEntitiesConvention(), order: Order.At.AbsoluteMax); // TODO consider using Max + conventions.Add(new EntitySubclassInitializerIsPostResourceConvention(), order: Order.At.AbsoluteMax); // TODO consider using Max + conventions.Add(new AddSubclassNameToRouteConvention(), order: Order.At.AbsoluteMax); // TODO consider using Max }); configurator.Buildtime.ConfigureGeneratedAssemblyCollection(generatedAssemblies => diff --git a/core/src/Baked/CodingStyle/Id/IdCodingStyleFeature.cs b/core/src/Baked/CodingStyle/Id/IdCodingStyleFeature.cs index 892e15a7f..3633c9bcd 100644 --- a/core/src/Baked/CodingStyle/Id/IdCodingStyleFeature.cs +++ b/core/src/Baked/CodingStyle/Id/IdCodingStyleFeature.cs @@ -18,7 +18,7 @@ public void Configure(LayerConfigurator configurator) { conventions.RemoveTypeAttribute( when: c => c.Type.Is(), - order: 10 + order: Order.At.Infra + 10 ); conventions.SetPropertyAttribute( when: c => c.Property.PropertyType.Is(), diff --git a/core/src/Baked/CodingStyle/Initializable/InitializableCodingStyleFeature.cs b/core/src/Baked/CodingStyle/Initializable/InitializableCodingStyleFeature.cs index 62bc5c6b3..a2a594788 100644 --- a/core/src/Baked/CodingStyle/Initializable/InitializableCodingStyleFeature.cs +++ b/core/src/Baked/CodingStyle/Initializable/InitializableCodingStyleFeature.cs @@ -1,7 +1,7 @@ using Baked.Architecture; using Baked.Business; +using Baked.Domain.Configuration; using Baked.Lifetime; -using Baked.RestApi; using NHibernate.Util; namespace Baked.CodingStyle.Initializable; @@ -21,16 +21,19 @@ public void Configure(LayerConfigurator configurator) c.Type.TryGetMembers(out var members) && members.Has() && _initializerNames.Any(i => members.Methods.Contains(i)), - attribute: () => new TransientAttribute() + attribute: () => new TransientAttribute(), + order: Order.At.Infra ); + conventions.SetMethodAttribute( when: c => _initializerNames.Contains(c.Method.Name), - attribute: () => new InitializerAttribute() + attribute: () => new InitializerAttribute(), + order: Order.At.Infra ); - conventions.Add(new AddInitializerParametersToQueryConvention()); - conventions.Add(new TargetUsingInitializerConvention(), order: RestApiLayer.MaxConventionOrder - 10); - conventions.Add(new RemoveInitializerNameFromRouteConvention(), order: RestApiLayer.MaxConventionOrder); + conventions.Add(new AddInitializerParametersToQueryConvention(), order: Order.At.Infra); + conventions.Add(new TargetUsingInitializerConvention(), order: Order.At.Max); + conventions.Add(new RemoveInitializerNameFromRouteConvention(), order: Order.At.AbsoluteMax); // TODO consider using Max }); } } \ No newline at end of file diff --git a/core/src/Baked/CodingStyle/Label/LabelCodingStyleFeature.cs b/core/src/Baked/CodingStyle/Label/LabelCodingStyleFeature.cs index fe1acc3de..3d0fcaa79 100644 --- a/core/src/Baked/CodingStyle/Label/LabelCodingStyleFeature.cs +++ b/core/src/Baked/CodingStyle/Label/LabelCodingStyleFeature.cs @@ -1,5 +1,6 @@ using Baked.Architecture; using Baked.Business; +using Baked.Domain.Configuration; namespace Baked.CodingStyle.Label; @@ -20,7 +21,7 @@ public void Configure(LayerConfigurator configurator) ) && _propertyNames.Contains(c.Property.Name), attribute: () => new LabelAttribute(), - order: 10 + order: Order.At.Infra + 10 ); }); } diff --git a/core/src/Baked/CodingStyle/Locatable/LocatableCodingStyleExtensions.cs b/core/src/Baked/CodingStyle/Locatable/LocatableCodingStyleExtensions.cs index 8dd491d49..962aa393a 100644 --- a/core/src/Baked/CodingStyle/Locatable/LocatableCodingStyleExtensions.cs +++ b/core/src/Baked/CodingStyle/Locatable/LocatableCodingStyleExtensions.cs @@ -2,8 +2,8 @@ using Baked.CodingStyle; using Baked.CodingStyle.Locatable; using Baked.Domain; +using Baked.Domain.Configuration; using Baked.Domain.Model; -using Baked.RestApi; using Baked.RestApi.Model; using Humanizer; using System.Diagnostics.CodeAnalysis; @@ -55,7 +55,7 @@ public string BuildLocateMany(ParameterModelAttribute locatorServiceParameter, s extension(IDomainModelConventionCollection conventions) { public void AddLocateAction() => - conventions.Add(new AddLocateActionConvention(), order: RestApiLayer.MaxConventionOrder - 20); + conventions.Add(new AddLocateActionConvention(), order: Order.At.Override.Min); } extension(ParameterModelAttribute parameter) diff --git a/core/src/Baked/CodingStyle/Locatable/LocatableCodingStyleFeature.cs b/core/src/Baked/CodingStyle/Locatable/LocatableCodingStyleFeature.cs index a01efd7fa..d74a145e2 100644 --- a/core/src/Baked/CodingStyle/Locatable/LocatableCodingStyleFeature.cs +++ b/core/src/Baked/CodingStyle/Locatable/LocatableCodingStyleFeature.cs @@ -1,5 +1,6 @@ using Baked.Architecture; using Baked.Business; +using Baked.Domain.Configuration; using Baked.RestApi; using Baked.RestApi.Model; using Microsoft.AspNetCore.Mvc; @@ -18,11 +19,11 @@ public void Configure(LayerConfigurator configurator) configurator.Domain.ConfigureConventions(conventions => { - conventions.Add(new ReplaceTargetWithIdParameterConvention()); - conventions.Add(new InitializeLocatablesConvention()); - conventions.Add(new LookupLocatableParameterConvention(), order: RestApiLayer.MaxConventionOrder - 20); - conventions.Add(new LookupLocatableParametersConvention(), order: RestApiLayer.MaxConventionOrder - 20); - conventions.Add(new TargetFromLocatorConvention(), order: RestApiLayer.MaxConventionOrder - 10); + conventions.Add(new ReplaceTargetWithIdParameterConvention(), order: Order.At.Infra); + conventions.Add(new InitializeLocatablesConvention(), order: Order.At.Infra); + conventions.Add(new LookupLocatableParameterConvention(), order: Order.At.Max - 10); + conventions.Add(new LookupLocatableParametersConvention(), order: Order.At.Max - 10); + conventions.Add(new TargetFromLocatorConvention(), order: Order.At.Max); }); configurator.Domain.ConfigureExportConfigurations(exports => diff --git a/core/src/Baked/CodingStyle/LocatableExtension/LocatableExtensionCodingStyleFeature.cs b/core/src/Baked/CodingStyle/LocatableExtension/LocatableExtensionCodingStyleFeature.cs index 69c632c5c..3474a41f0 100644 --- a/core/src/Baked/CodingStyle/LocatableExtension/LocatableExtensionCodingStyleFeature.cs +++ b/core/src/Baked/CodingStyle/LocatableExtension/LocatableExtensionCodingStyleFeature.cs @@ -1,6 +1,6 @@ using Baked.Architecture; using Baked.Business; -using Baked.RestApi; +using Baked.Domain.Configuration; using Baked.RestApi.Model; namespace Baked.CodingStyle.LocatableExtension; @@ -32,7 +32,7 @@ public void Configure(LayerConfigurator configurator) return locatableType.Apply(t => new LocatableExtensionAttribute(t)); }, - order: 20 + order: Order.At.Infra + 20 ); conventions.SetPropertyAttribute( when: c => c.Type.Has(), @@ -42,7 +42,7 @@ public void Configure(LayerConfigurator configurator) return c.Domain.Types[locatableExtensionAttribute.LocatableType].GetMembers().Properties.First(p => p.CustomAttributes.Contains()).Get(); }, - order: 20 + order: Order.At.Infra + 20 ); conventions.SetTypeAttribute( when: c => c.Type.Has(), @@ -54,7 +54,7 @@ public void Configure(LayerConfigurator configurator) set(c.Type, namespaceAttribute); }, - order: 20 + order: Order.At.Infra + 20 ); conventions.SetTypeAttribute( when: c => c.Type.Has(), @@ -68,11 +68,11 @@ public void Configure(LayerConfigurator configurator) set(c.Type, new LocatableAttribute()); }, - order: 20 + order: Order.At.Infra + 20 ); - conventions.Add(new ExtensionsUnderLocatablesConvention(), order: RestApiLayer.MaxConventionOrder); - conventions.Add(new ExtensionsAreServedUnderLocatableRoutesConvention(), order: RestApiLayer.MaxConventionOrder); + conventions.Add(new ExtensionsUnderLocatablesConvention(), order: Order.At.AbsoluteMax); // TODO consider using Order.At.Max + conventions.Add(new ExtensionsAreServedUnderLocatableRoutesConvention(), order: Order.At.AbsoluteMax); // TODO consider using Order.At.Max }); configurator.Buildtime.ConfigureGeneratedAssemblyCollection(generatedAssemblies => diff --git a/core/src/Baked/CodingStyle/NamespaceAsRoute/NamespaceAsRouteCodingStyleFeature.cs b/core/src/Baked/CodingStyle/NamespaceAsRoute/NamespaceAsRouteCodingStyleFeature.cs index 70bf6e2f2..212f1f71d 100644 --- a/core/src/Baked/CodingStyle/NamespaceAsRoute/NamespaceAsRouteCodingStyleFeature.cs +++ b/core/src/Baked/CodingStyle/NamespaceAsRoute/NamespaceAsRouteCodingStyleFeature.cs @@ -1,5 +1,5 @@ using Baked.Architecture; -using Baked.RestApi; +using Baked.Domain.Configuration; namespace Baked.CodingStyle.NamespaceAsRoute; @@ -9,7 +9,7 @@ public void Configure(LayerConfigurator configurator) { configurator.Domain.ConfigureConventions(conventions => { - conventions.Add(new UseNamespaceForBaseRouteConvention(), order: RestApiLayer.MaxConventionOrder - 10); + conventions.Add(new UseNamespaceForBaseRouteConvention(), order: Order.At.Max); }); } } \ No newline at end of file diff --git a/core/src/Baked/CodingStyle/ObjectAsJson/ObjectAsJsonCodingStyleFeature.cs b/core/src/Baked/CodingStyle/ObjectAsJson/ObjectAsJsonCodingStyleFeature.cs index b1e3e9dc7..85ea0c2bf 100644 --- a/core/src/Baked/CodingStyle/ObjectAsJson/ObjectAsJsonCodingStyleFeature.cs +++ b/core/src/Baked/CodingStyle/ObjectAsJson/ObjectAsJsonCodingStyleFeature.cs @@ -1,4 +1,5 @@ using Baked.Architecture; +using Baked.Domain.Configuration; using Baked.RestApi.Model; using FluentNHibernate.Conventions.Helpers; using Microsoft.Extensions.DependencyInjection; @@ -14,10 +15,11 @@ public void Configure(LayerConfigurator configurator) { conventions.SetTypeAttribute( attribute: () => new ApiInputAttribute(), - when: c => c.Type.Is() + when: c => c.Type.Is(), + order: Order.At.Infra ); - conventions.Add(new SingleObjectParametersDontUseRequestClassConvention()); + conventions.Add(new SingleObjectParametersDontUseRequestClassConvention(), order: Order.At.Infra); }); configurator.DataAccess.ConfigureAutoPersistenceModel(model => diff --git a/core/src/Baked/CodingStyle/Query/QueryCodingStyleFeature.cs b/core/src/Baked/CodingStyle/Query/QueryCodingStyleFeature.cs index 3194696ca..ed84fb04a 100644 --- a/core/src/Baked/CodingStyle/Query/QueryCodingStyleFeature.cs +++ b/core/src/Baked/CodingStyle/Query/QueryCodingStyleFeature.cs @@ -1,5 +1,6 @@ using Baked.Architecture; using Baked.Business; +using Baked.Domain.Configuration; using Baked.Domain.Model; using Baked.RestApi.Conventions; using Humanizer; @@ -26,13 +27,13 @@ public void Configure(LayerConfigurator configurator) var locatable = c.Type.Get(); queryType.Apply(qt => locatable.QueryType = qt); }, - order: 30 + order: Order.At.Infra + 30 ); - conventions.Add(new AutoHttpMethodConvention([(Regexes.StartsWithFirstBySingleByOrBy, HttpMethod.Get)]), order: -10); + conventions.Add(new AutoHttpMethodConvention([(Regexes.StartsWithFirstBySingleByOrBy, HttpMethod.Get)]), order: Order.At.Infra - 10); conventions.Add(new RemoveFromRouteConvention(["FirstBy", "SingleBy", "By"], _whenContext: c => c.Type.TryGetMetadata(out var metadata) && metadata.Has() - )); + ), order: Order.At.Infra); }); } } \ No newline at end of file diff --git a/core/src/Baked/CodingStyle/QueryMethod/QueryMethodCodingStyleFeature.cs b/core/src/Baked/CodingStyle/QueryMethod/QueryMethodCodingStyleFeature.cs index dee0c3c5e..7d14476d1 100644 --- a/core/src/Baked/CodingStyle/QueryMethod/QueryMethodCodingStyleFeature.cs +++ b/core/src/Baked/CodingStyle/QueryMethod/QueryMethodCodingStyleFeature.cs @@ -1,5 +1,6 @@ using Baked.Architecture; using Baked.Business; +using Baked.Domain.Configuration; namespace Baked.CodingStyle.QueryMethod; @@ -25,11 +26,12 @@ public void Configure(LayerConfigurator configurator) conventions.SetMethodAttribute( when: c => c.Type.Has() && _queryMethodNames.Contains(c.Method.Name), attribute: () => new QueryMethodAttribute(), - order: 40 + order: Order.At.Infra + 40 ); conventions.AddMethodAttributeConfiguration( when: c => c.Method.DefaultOverload.Parameters.All(p => p.IsOptional), - attribute: qm => qm.AllParametersAreOptional = true + attribute: qm => qm.AllParametersAreOptional = true, + order: Order.At.Infra ); conventions.AddMethodAttributeConfiguration( when: c => c.Method.DefaultOverload.Parameters.Any(p => _primaryParameterNames.Contains(p.Name)), @@ -42,25 +44,26 @@ public void Configure(LayerConfigurator configurator) ); qm.PrimaryParameterName = primaryParameter.Name; - } + }, + order: Order.At.Infra ); conventions.SetParameterAttribute( when: c => c.Method.Has() && _takeParameterNames.Contains(c.Parameter.Name), attribute: () => new PagingAttribute(PagingAttribute.Role.Take), - order: 40 + order: Order.At.Infra + 40 ); conventions.SetParameterAttribute( when: c => c.Method.Has() && _skipParameterNames.Contains(c.Parameter.Name), attribute: () => new PagingAttribute(PagingAttribute.Role.Skip), - order: 40 + order: Order.At.Infra + 40 ); conventions.SetParameterAttribute( when: c => c.Method.Has() && _sortingParameterNames.Contains(c.Parameter.Name), attribute: () => new SortingAttribute(), - order: 40 + order: Order.At.Infra + 40 ); }); } diff --git a/core/src/Baked/CodingStyle/RecordsAreDtos/RecordsAreDtosCodingStyleFeature.cs b/core/src/Baked/CodingStyle/RecordsAreDtos/RecordsAreDtosCodingStyleFeature.cs index c93add484..8d7c7c53a 100644 --- a/core/src/Baked/CodingStyle/RecordsAreDtos/RecordsAreDtosCodingStyleFeature.cs +++ b/core/src/Baked/CodingStyle/RecordsAreDtos/RecordsAreDtosCodingStyleFeature.cs @@ -1,4 +1,5 @@ using Baked.Architecture; +using Baked.Domain.Configuration; using Baked.RestApi.Model; namespace Baked.CodingStyle.RecordsAreDtos; @@ -13,7 +14,8 @@ public void Configure(LayerConfigurator configurator) attribute: () => new ApiInputAttribute(), when: c => c.Type.TryGetMembers(out var members) && - members.Methods.Contains("$") // if type is record + members.Methods.Contains("$"), // if type is record + order: Order.At.Infra ); }); } diff --git a/core/src/Baked/CodingStyle/RemainingServicesAreSingleton/RemainingServicesAreSingletonCodingStyleFeature.cs b/core/src/Baked/CodingStyle/RemainingServicesAreSingleton/RemainingServicesAreSingletonCodingStyleFeature.cs index 34f734542..e387b9ef3 100644 --- a/core/src/Baked/CodingStyle/RemainingServicesAreSingleton/RemainingServicesAreSingletonCodingStyleFeature.cs +++ b/core/src/Baked/CodingStyle/RemainingServicesAreSingleton/RemainingServicesAreSingletonCodingStyleFeature.cs @@ -1,7 +1,7 @@ using Baked.Architecture; using Baked.Business; +using Baked.Domain.Configuration; using Baked.Lifetime; -using Baked.RestApi; namespace Baked.CodingStyle.RemainingServicesAreSingleton; @@ -21,7 +21,7 @@ public void Configure(LayerConfigurator configurator) !members.Has() && !members.Has() && members.Properties.All(p => !p.IsPublic), - order: RestApiLayer.MaxConventionOrder - 10 + order: Order.At.Max ); }); } diff --git a/core/src/Baked/CodingStyle/RichEntity/RichEntityCodingStyleFeature.cs b/core/src/Baked/CodingStyle/RichEntity/RichEntityCodingStyleFeature.cs index 0df133d17..c62783b0a 100644 --- a/core/src/Baked/CodingStyle/RichEntity/RichEntityCodingStyleFeature.cs +++ b/core/src/Baked/CodingStyle/RichEntity/RichEntityCodingStyleFeature.cs @@ -1,5 +1,6 @@ using Baked.Architecture; using Baked.Business; +using Baked.Domain.Configuration; using Baked.Domain.Model; using Baked.Orm; using Baked.RestApi.Model; @@ -20,7 +21,8 @@ public void Configure(LayerConfigurator configurator) TryGetEntityContextParameter(members, out var entityContextParameter) && entityContextParameter.ParameterType.TryGetGenerics(out var entityContextGenerics) && entityContextGenerics.GenericTypeArguments.First().Model == c.Type, - attribute: () => new EntityAttribute() + attribute: () => new EntityAttribute(), + order: Order.At.Infra ); conventions.SetTypeAttribute( when: c => c.Type.Has(), @@ -28,17 +30,18 @@ public void Configure(LayerConfigurator configurator) { set(c.Type, new ApiInputAttribute()); set(c.Type, new LocatableAttribute()); - } + }, + order: Order.At.Infra ); conventions.SetMethodAttribute( when: c => c.Type.Has() && c.Method.Has() && c.Method.Overloads.Any(o => o.IsPublic && !o.IsStatic && !o.IsSpecialName && o.AllParametersAreApiInput()), attribute: c => new ActionModelAttribute(), - order: 30 + order: Order.At.Infra + 30 ); - conventions.Add(new EntityInitializerIsPostResourceConvention()); + conventions.Add(new EntityInitializerIsPostResourceConvention(), order: Order.At.Infra); }); configurator.DataAccess.ConfigureNHibernateInterceptor(interceptor => diff --git a/core/src/Baked/CodingStyle/RichTransient/RichTransientCodingStyleFeature.cs b/core/src/Baked/CodingStyle/RichTransient/RichTransientCodingStyleFeature.cs index 50318cba9..a80b37b5c 100644 --- a/core/src/Baked/CodingStyle/RichTransient/RichTransientCodingStyleFeature.cs +++ b/core/src/Baked/CodingStyle/RichTransient/RichTransientCodingStyleFeature.cs @@ -1,5 +1,6 @@ using Baked.Architecture; using Baked.Business; +using Baked.Domain.Configuration; using Baked.Domain.Model; using Baked.Lifetime; using Baked.RestApi.Model; @@ -40,7 +41,7 @@ public void Configure(LayerConfigurator configurator) set(c.Type, new ApiInputAttribute()); set(c.Type, new LocatableAttribute()); }, - order: 10 + order: Order.At.Infra + 10 ); conventions.AddTypeAttributeConfiguration( when: c => c.Type.Has(), @@ -56,7 +57,7 @@ public void Configure(LayerConfigurator configurator) locatable.IsAsync = initializer.DefaultOverload.ReturnType.IsAssignableTo(); }, - order: 10 + order: Order.At.Infra + 10 ); conventions.SetMethodAttribute( when: c => @@ -66,11 +67,11 @@ public void Configure(LayerConfigurator configurator) c.Method.Has() && c.Method.DefaultOverload.IsPublic, attribute: c => new ActionModelAttribute(), - order: 20 + order: Order.At.Infra + 20 ); - conventions.Add(new RichTransientUnderPluralGroupConvention()); - conventions.Add(new RichTransientInitializerIsGetResourceConvention(), order: 10); + conventions.Add(new RichTransientUnderPluralGroupConvention(), order: Order.At.Infra); + conventions.Add(new RichTransientInitializerIsGetResourceConvention(), order: Order.At.Infra + 10); }); configurator.Buildtime.ConfigureGeneratedAssemblyCollection(generatedAssemblies => diff --git a/core/src/Baked/CodingStyle/ScopedBySuffix/ScopedBySuffixCodingStyleFeature.cs b/core/src/Baked/CodingStyle/ScopedBySuffix/ScopedBySuffixCodingStyleFeature.cs index e127717ec..c80a2a60b 100644 --- a/core/src/Baked/CodingStyle/ScopedBySuffix/ScopedBySuffixCodingStyleFeature.cs +++ b/core/src/Baked/CodingStyle/ScopedBySuffix/ScopedBySuffixCodingStyleFeature.cs @@ -1,5 +1,6 @@ using Baked.Architecture; using Baked.Business; +using Baked.Domain.Configuration; using Baked.Lifetime; namespace Baked.CodingStyle.ScopedBySuffix; @@ -17,7 +18,8 @@ public void Configure(LayerConfigurator configurator) c.Type.IsClass && !c.Type.IsAbstract && c.Type.TryGetMetadata(out var metadata) && metadata.Has() && - _suffixes.Any(suffix => c.Type.Name.EndsWith(suffix)) + _suffixes.Any(suffix => c.Type.Name.EndsWith(suffix)), + order: Order.At.Infra ); }); } diff --git a/core/src/Baked/CodingStyle/Unique/UniqueCodingStyleFeature.cs b/core/src/Baked/CodingStyle/Unique/UniqueCodingStyleFeature.cs index ab27cfdee..118480b97 100644 --- a/core/src/Baked/CodingStyle/Unique/UniqueCodingStyleFeature.cs +++ b/core/src/Baked/CodingStyle/Unique/UniqueCodingStyleFeature.cs @@ -1,5 +1,6 @@ using Baked.Architecture; using Baked.Business; +using Baked.Domain.Configuration; using Baked.Orm; namespace Baked.CodingStyle.Unique; @@ -21,7 +22,7 @@ locatable.QueryType is not null && query.Methods.Contains($"AnyBy{c.Property.Name}") ), attribute: c => new UniqueAttribute(), - order: 30 + order: Order.At.Infra + 30 ); }); } diff --git a/core/src/Baked/CodingStyle/UriReturnIsRedirect/UriReturnIsRedirectCodingStyleFeature.cs b/core/src/Baked/CodingStyle/UriReturnIsRedirect/UriReturnIsRedirectCodingStyleFeature.cs index 20b755974..f4339e703 100644 --- a/core/src/Baked/CodingStyle/UriReturnIsRedirect/UriReturnIsRedirectCodingStyleFeature.cs +++ b/core/src/Baked/CodingStyle/UriReturnIsRedirect/UriReturnIsRedirectCodingStyleFeature.cs @@ -1,4 +1,5 @@ using Baked.Architecture; +using Baked.Domain.Configuration; namespace Baked.CodingStyle.UriReturnIsRedirect; @@ -8,9 +9,9 @@ public void Configure(LayerConfigurator configurator) { configurator.Domain.ConfigureConventions(conventions => { - conventions.Add(new UriReturnIsRedirectConvention()); - conventions.Add(new UriReturnWithoutParameterIsGetConvention()); - conventions.Add(new UriReturnWithParameterIsFormPostConvention(), order: -10); + conventions.Add(new UriReturnIsRedirectConvention(), order: Order.At.Infra); + conventions.Add(new UriReturnWithoutParameterIsGetConvention(), order: Order.At.Infra); + conventions.Add(new UriReturnWithParameterIsFormPostConvention(), order: Order.At.Infra - 10); }); configurator.RestApi.ConfigureApiModel(api => diff --git a/core/src/Baked/CodingStyle/UseBuiltInTypes/UseBuiltInTypesCodingStyleFeature.cs b/core/src/Baked/CodingStyle/UseBuiltInTypes/UseBuiltInTypesCodingStyleFeature.cs index 9017a1f5e..23f8be88b 100644 --- a/core/src/Baked/CodingStyle/UseBuiltInTypes/UseBuiltInTypesCodingStyleFeature.cs +++ b/core/src/Baked/CodingStyle/UseBuiltInTypes/UseBuiltInTypesCodingStyleFeature.cs @@ -1,5 +1,5 @@ using Baked.Architecture; -using Baked.RestApi; +using Baked.Domain.Configuration; using Baked.RestApi.Model; using FluentNHibernate.Conventions.Helpers; using Microsoft.Extensions.DependencyInjection; @@ -22,7 +22,7 @@ public void Configure(LayerConfigurator configurator) c.Type.Is() || c.Type.IsAssignableTo(typeof(IParsable<>)) || c.Type.IsAssignableTo(typeof(string)), - order: RestApiLayer.MinConventionOrder + order: Order.At.Infra.AbsoluteMin // TODO consider using Order.At.Infra.Min ); conventions.SetTypeAttribute( attribute: () => new ApiInputAttribute(), @@ -31,7 +31,7 @@ public void Configure(LayerConfigurator configurator) c.Type.IsGenericType && c.Type.TryGetGenerics(out var generics) && generics.GenericTypeArguments.FirstOrDefault()?.Model.TryGetMetadata(out var genericArgMetadata) == true && genericArgMetadata.Has(), - order: 20 + order: Order.At.Infra + 20 ); conventions.SetTypeAttribute( attribute: () => new ApiInputAttribute(), @@ -39,12 +39,12 @@ public void Configure(LayerConfigurator configurator) c.Type.IsArray && c.Type.TryGetGenerics(out var generics) && generics.ElementType?.TryGetMetadata(out var elementMetadata) == true && elementMetadata.Has(), - order: 20 + order: Order.At.Infra + 20 ); - conventions.Add(new BoolDefaultValueConvention()); - conventions.Add(new SetDefaultValueForEnumConvention()); - conventions.Add(new StringDefaultValueConvention()); + conventions.Add(new BoolDefaultValueConvention(), order: Order.At.Infra); + conventions.Add(new SetDefaultValueForEnumConvention(), order: Order.At.Infra); + conventions.Add(new StringDefaultValueConvention(), order: Order.At.Infra); }); configurator.DataAccess.ConfigureAutoPersistenceModel(model => diff --git a/core/src/Baked/CodingStyle/UseNullableTypes/UseNullableTypesCodingStyleFeature.cs b/core/src/Baked/CodingStyle/UseNullableTypes/UseNullableTypesCodingStyleFeature.cs index ac19f11a1..087c35cf8 100644 --- a/core/src/Baked/CodingStyle/UseNullableTypes/UseNullableTypesCodingStyleFeature.cs +++ b/core/src/Baked/CodingStyle/UseNullableTypes/UseNullableTypesCodingStyleFeature.cs @@ -1,5 +1,5 @@ using Baked.Architecture; -using Baked.RestApi; +using Baked.Domain.Configuration; using Baked.RestApi.Model; using System.ComponentModel.DataAnnotations; using System.Diagnostics.CodeAnalysis; @@ -21,7 +21,7 @@ public void Configure(LayerConfigurator configurator) c.Type.GenericTypeArguments.FirstOrDefault()?.Model.TryGetMetadata(out var genericArgumentMetadata) == true && genericArgumentMetadata.Has(), attribute: () => new ApiInputAttribute(), - order: RestApiLayer.MinConventionOrder + order: Order.At.Infra.AbsoluteMin // TODO consider using Order.At.Infra.Min ); conventions.SetParameterAttribute( @@ -36,16 +36,17 @@ public void Configure(LayerConfigurator configurator) return !nullable; }, attribute: () => new NotNullAttribute(), - order: RestApiLayer.MinConventionOrder + order: Order.At.Infra.Min ); conventions.SetParameterAttribute( when: c => !c.Parameter.IsOptional && !c.Parameter.IsNullable, - attribute: () => new RequiredAttribute() + attribute: () => new RequiredAttribute(), + order: Order.At.Infra ); - conventions.Add(new RequiredParametersAreRequiredInApiModelConvention()); - conventions.Add(new SetDefaultValueForNullableEnumConvention()); + conventions.Add(new RequiredParametersAreRequiredInApiModelConvention(), order: Order.At.Infra); + conventions.Add(new SetDefaultValueForNullableEnumConvention(), order: Order.At.Infra); }); configurator.RestApi.ConfigureApiModel(api => diff --git a/core/src/Baked/CodingStyle/ValueType/ValueTypeCodingStyleFeature.cs b/core/src/Baked/CodingStyle/ValueType/ValueTypeCodingStyleFeature.cs index b6a947fcf..2125b6b28 100644 --- a/core/src/Baked/CodingStyle/ValueType/ValueTypeCodingStyleFeature.cs +++ b/core/src/Baked/CodingStyle/ValueType/ValueTypeCodingStyleFeature.cs @@ -1,5 +1,6 @@ using Baked.Architecture; using Baked.Business; +using Baked.Domain.Configuration; using Baked.RestApi; using Microsoft.Extensions.DependencyInjection; using Microsoft.OpenApi; @@ -25,7 +26,8 @@ public void Configure(LayerConfigurator configurator) c.Type.Namespace is not null && !c.Type.Namespace.StartsWith("System") && c.Type.IsAssignableTo(typeof(IParsable<>)), - attribute: () => new ValueTypeAttribute() + attribute: () => new ValueTypeAttribute(), + order: Order.At.Infra ); }); diff --git a/core/src/Baked/Database/MySql/MySqlDatabaseFeature.cs b/core/src/Baked/Database/MySql/MySqlDatabaseFeature.cs index 86509b0b0..612bda128 100644 --- a/core/src/Baked/Database/MySql/MySqlDatabaseFeature.cs +++ b/core/src/Baked/Database/MySql/MySqlDatabaseFeature.cs @@ -1,4 +1,5 @@ using Baked.Architecture; +using Baked.Domain.Configuration; using Baked.Runtime; using FluentNHibernate.Cfg.Db; using Microsoft.Extensions.DependencyInjection; @@ -33,7 +34,7 @@ public void Configure(LayerConfigurator configurator) configurator.Domain.ConfigureConventions(conventions => { - conventions.Add(new AddFlatTransactionToActionConvention()); + conventions.Add(new AddFlatTransactionToActionConvention(), order: Order.At.Infra); }); } } \ No newline at end of file diff --git a/core/src/Baked/Database/Oracle/OracleDatabaseFeature.cs b/core/src/Baked/Database/Oracle/OracleDatabaseFeature.cs index 30000bcdf..b8b681526 100644 --- a/core/src/Baked/Database/Oracle/OracleDatabaseFeature.cs +++ b/core/src/Baked/Database/Oracle/OracleDatabaseFeature.cs @@ -1,4 +1,5 @@ using Baked.Architecture; +using Baked.Domain.Configuration; using Baked.Runtime; using FluentNHibernate.Cfg.Db; using Microsoft.Extensions.DependencyInjection; @@ -38,7 +39,7 @@ public void Configure(LayerConfigurator configurator) configurator.Domain.ConfigureConventions(conventions => { - conventions.Add(new AddFlatTransactionToActionConvention()); + conventions.Add(new AddFlatTransactionToActionConvention(), order: Order.At.Infra); }); } } \ No newline at end of file diff --git a/core/src/Baked/Database/PostgreSql/PostgreSqlDatabaseFeature.cs b/core/src/Baked/Database/PostgreSql/PostgreSqlDatabaseFeature.cs index a658729e5..6f50af76f 100644 --- a/core/src/Baked/Database/PostgreSql/PostgreSqlDatabaseFeature.cs +++ b/core/src/Baked/Database/PostgreSql/PostgreSqlDatabaseFeature.cs @@ -1,4 +1,5 @@ using Baked.Architecture; +using Baked.Domain.Configuration; using Baked.Runtime; using FluentNHibernate.Cfg.Db; using Microsoft.Extensions.DependencyInjection; @@ -34,7 +35,7 @@ public void Configure(LayerConfigurator configurator) configurator.Domain.ConfigureConventions(conventions => { - conventions.Add(new AddFlatTransactionToActionConvention()); + conventions.Add(new AddFlatTransactionToActionConvention(), order: Order.At.Infra); }); } } \ No newline at end of file diff --git a/core/src/Baked/Database/Sqlite/SqliteDatabaseFeature.cs b/core/src/Baked/Database/Sqlite/SqliteDatabaseFeature.cs index 66f0ef944..4f06fea55 100644 --- a/core/src/Baked/Database/Sqlite/SqliteDatabaseFeature.cs +++ b/core/src/Baked/Database/Sqlite/SqliteDatabaseFeature.cs @@ -1,5 +1,6 @@ using Baked.Architecture; using Baked.DataAccess.Sqlite; +using Baked.Domain.Configuration; using Baked.Runtime; using Microsoft.Extensions.DependencyInjection; @@ -40,7 +41,7 @@ public void Configure(LayerConfigurator configurator) configurator.Domain.ConfigureConventions(conventions => { - conventions.Add(new AddFlatTransactionToActionConvention()); + conventions.Add(new AddFlatTransactionToActionConvention(), order: Order.At.Infra); }); } } \ No newline at end of file diff --git a/core/src/Baked/Domain/Configuration/DomainModelBuilderOptions.cs b/core/src/Baked/Domain/Configuration/DomainModelBuilderOptions.cs index a85af65e3..473801725 100644 --- a/core/src/Baked/Domain/Configuration/DomainModelBuilderOptions.cs +++ b/core/src/Baked/Domain/Configuration/DomainModelBuilderOptions.cs @@ -11,7 +11,7 @@ public class DomainModelBuilderOptions public DomainIndexOptions Index { get; set; } = new(); public Func, MethodOverloadModel> DefaultOverloadSelector { get; set; } = overloads => overloads.First(); public Action? OnComplete { get; set; } - public ICollection ConventionLevels { get; } = [nameof(Domain)]; + public IList ConventionLevels { get; } = [nameof(Domain)]; public string DefaultConventionLevel { get; set; } = nameof(Domain); public class BindingFlagOptions diff --git a/core/src/Baked/Domain/Configuration/DomainModelPostBuilder.cs b/core/src/Baked/Domain/Configuration/DomainModelPostBuilder.cs index 95510ab3b..86b306c11 100644 --- a/core/src/Baked/Domain/Configuration/DomainModelPostBuilder.cs +++ b/core/src/Baked/Domain/Configuration/DomainModelPostBuilder.cs @@ -14,36 +14,36 @@ public void EndBuild() using (Diagnostics.Start(nameof(DomainModelPostBuilder), onDispose: _options.OnComplete)) { var contexts = new DomainModelConventionContexts(Model); - var conventionsRequiringIndex = new List(); - var restOfTheConventions = new List(); + var conventionsBeforeBuildingIndexes = new List(); + var conventionsAfterBuildingIndexes = new List(); foreach (var convention in _conventions.OrderBy(c => c.Order).Select(c => c.Convention)) { - if (convention is IAddRemoveAttributeConvention addRemove && addRemove.AttributeRequiresIndex) + if (convention.BeforeBuildingIndexes) { - conventionsRequiringIndex.Add(convention); + conventionsBeforeBuildingIndexes.Add(convention); } else { - restOfTheConventions.Add(convention); + conventionsAfterBuildingIndexes.Add(convention); } } - foreach (var convention in conventionsRequiringIndex) + foreach (var convention in conventionsBeforeBuildingIndexes) { contexts.Apply(convention); } - BuildIndices(); + BuildIndexes(); - foreach (var convention in restOfTheConventions) + foreach (var convention in conventionsAfterBuildingIndexes) { contexts.Apply(convention); } } } - void BuildIndices() + void BuildIndexes() { foreach (var index in _options.Index.Type) { diff --git a/core/src/Baked/Domain/Configuration/IAddRemoveAttributeConvention.cs b/core/src/Baked/Domain/Configuration/IAddRemoveAttributeConvention.cs deleted file mode 100644 index 5dc05059a..000000000 --- a/core/src/Baked/Domain/Configuration/IAddRemoveAttributeConvention.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Baked.Domain.Configuration; - -public interface IAddRemoveAttributeConvention : IDomainModelConvention -{ - bool AttributeRequiresIndex { get; } -} \ No newline at end of file diff --git a/core/src/Baked/Domain/Configuration/IDomainModelConvention.cs b/core/src/Baked/Domain/Configuration/IDomainModelConvention.cs index e8125e856..61f2bdf0d 100644 --- a/core/src/Baked/Domain/Configuration/IDomainModelConvention.cs +++ b/core/src/Baked/Domain/Configuration/IDomainModelConvention.cs @@ -1,6 +1,9 @@ namespace Baked.Domain.Configuration; -public interface IDomainModelConvention; +public interface IDomainModelConvention +{ + public bool BeforeBuildingIndexes => false; +} public interface IDomainModelConvention : IDomainModelConvention { diff --git a/core/src/Baked/Domain/Configuration/Order.cs b/core/src/Baked/Domain/Configuration/Order.cs index b5f0cee75..139dc1bbc 100644 --- a/core/src/Baked/Domain/Configuration/Order.cs +++ b/core/src/Baked/Domain/Configuration/Order.cs @@ -44,8 +44,12 @@ public Order() public Order Offset(int value) => Clone(offset: _offset + value); - public Order Level(string level) => - Clone(level: level, global: false); + public Order Level(string level, + bool @default = false + ) => Clone( + level: @default ? _level ?? level : level, + global: false + ); Order Clone( int? offset = default, diff --git a/core/src/Baked/Domain/Conventions/AddAttributeConvention.cs b/core/src/Baked/Domain/Conventions/AddAttributeConvention.cs index 0017dfe6a..89510d83f 100644 --- a/core/src/Baked/Domain/Conventions/AddAttributeConvention.cs +++ b/core/src/Baked/Domain/Conventions/AddAttributeConvention.cs @@ -7,13 +7,13 @@ namespace Baked.Domain.Conventions; public class AddAttributeConvention( Action> _apply, Func _when, - bool attributeRequiresIndex = true -) : IDomainModelConvention, IAddRemoveAttributeConvention + bool beforeBuildingIndexes = true +) : IDomainModelConvention where TModelContext : DomainModelContext { readonly Trace _trace = Trace.Here(); - bool IAddRemoveAttributeConvention.AttributeRequiresIndex => attributeRequiresIndex; + bool IDomainModelConvention.BeforeBuildingIndexes => beforeBuildingIndexes; public void Apply(TModelContext context) { diff --git a/core/src/Baked/Domain/Conventions/RemoveAttributeConvention.cs b/core/src/Baked/Domain/Conventions/RemoveAttributeConvention.cs index f86f39c4d..502eca150 100644 --- a/core/src/Baked/Domain/Conventions/RemoveAttributeConvention.cs +++ b/core/src/Baked/Domain/Conventions/RemoveAttributeConvention.cs @@ -6,10 +6,10 @@ namespace Baked.Domain.Conventions; public class RemoveAttributeConvention( Action> _apply, Func _when, - bool attributeRequiresIndex = true -) : IDomainModelConvention, IAddRemoveAttributeConvention where TAttribute : Attribute + bool beforeBuildingIndexes = true +) : IDomainModelConvention where TAttribute : Attribute { - bool IAddRemoveAttributeConvention.AttributeRequiresIndex => attributeRequiresIndex; + bool IDomainModelConvention.BeforeBuildingIndexes => beforeBuildingIndexes; public void Apply(TModelContext model) { diff --git a/core/src/Baked/Domain/Conventions/SetAttributeConvention.cs b/core/src/Baked/Domain/Conventions/SetAttributeConvention.cs index 197cfaa18..7ddf4da92 100644 --- a/core/src/Baked/Domain/Conventions/SetAttributeConvention.cs +++ b/core/src/Baked/Domain/Conventions/SetAttributeConvention.cs @@ -7,13 +7,13 @@ namespace Baked.Domain.Conventions; public class SetAttributeConvention( Action> _apply, Func _when, - bool attributeRequiresIndex = true -) : IDomainModelConvention, IAddRemoveAttributeConvention + bool beforeBuildingIndexes = true +) : IDomainModelConvention where TModelContext : DomainModelContext { readonly Trace _trace = Trace.Here(); - bool IAddRemoveAttributeConvention.AttributeRequiresIndex => attributeRequiresIndex; + bool IDomainModelConvention.BeforeBuildingIndexes => beforeBuildingIndexes; public void Apply(TModelContext context) { diff --git a/core/src/Baked/Domain/DomainExtensions.cs b/core/src/Baked/Domain/DomainExtensions.cs index b824eb19b..9a71eb87e 100644 --- a/core/src/Baked/Domain/DomainExtensions.cs +++ b/core/src/Baked/Domain/DomainExtensions.cs @@ -249,151 +249,163 @@ public bool IsAutoProperty } } + extension(Order order) + { + public Order Infra => + order.Level("Infra"); + + public Order Domain => + order.Level(nameof(Domain)); + + public Order Override => + order.Level("Override"); + } + extension(IDomainModelConventionCollection conventions) { public void SetTypeAttribute(Func attribute, Func when, - bool requiresIndex = true, + bool beforeBuildingIndexes = true, Order order = default - ) => conventions.SetTypeAttribute((context, set) => set(context.Type, attribute()), when, requiresIndex, order); + ) => conventions.SetTypeAttribute((context, set) => set(context.Type, attribute()), when, beforeBuildingIndexes, order); public void SetTypeAttribute(Func attribute, Func when, - bool requiresIndex = true, + bool beforeBuildingIndexes = true, Order order = default - ) => conventions.SetTypeAttribute((context, set) => set(context.Type, attribute(context)), when, requiresIndex, order); + ) => conventions.SetTypeAttribute((context, set) => set(context.Type, attribute(context)), when, beforeBuildingIndexes, order); public void SetTypeAttribute(Action> apply, Func when, - bool requiresIndex = true, + bool beforeBuildingIndexes = true, Order order = default - ) => conventions.Add(new SetAttributeConvention(apply, when, attributeRequiresIndex: requiresIndex), order); + ) => conventions.Add(new SetAttributeConvention(apply, when, beforeBuildingIndexes: beforeBuildingIndexes), order); public void AddTypeAttribute(Func attribute, Func when, - bool requiresIndex = true, + bool beforeBuildingIndexes = true, Order order = default - ) => conventions.AddTypeAttribute((context, add) => add(context.Type, attribute()), when, requiresIndex, order); + ) => conventions.AddTypeAttribute((context, add) => add(context.Type, attribute()), when, beforeBuildingIndexes, order); public void AddTypeAttribute(Func attribute, Func when, - bool requiresIndex = true, + bool beforeBuildingIndexes = true, Order order = default - ) => conventions.AddTypeAttribute((context, add) => add(context.Type, attribute(context)), when, requiresIndex, order); + ) => conventions.AddTypeAttribute((context, add) => add(context.Type, attribute(context)), when, beforeBuildingIndexes, order); public void AddTypeAttribute(Action> apply, Func when, - bool requiresIndex = true, + bool beforeBuildingIndexes = true, Order order = default - ) => conventions.Add(new AddAttributeConvention(apply, when, attributeRequiresIndex: requiresIndex), order); + ) => conventions.Add(new AddAttributeConvention(apply, when, beforeBuildingIndexes: beforeBuildingIndexes), order); public void RemoveTypeAttribute(Func when, - bool requiresIndex = true, + bool beforeBuildingIndexes = true, Order order = default ) where TAttribute : Attribute => - conventions.Add(new RemoveAttributeConvention((context, remove) => remove(context.Type), when, attributeRequiresIndex: requiresIndex), order); + conventions.Add(new RemoveAttributeConvention((context, remove) => remove(context.Type), when, beforeBuildingIndexes: beforeBuildingIndexes), order); public void SetPropertyAttribute(Func attribute, Func when, - bool requiresIndex = true, + bool beforeBuildingIndexes = true, Order order = default - ) => conventions.SetPropertyAttribute((context, set) => set(context.Property, attribute()), when, requiresIndex, order); + ) => conventions.SetPropertyAttribute((context, set) => set(context.Property, attribute()), when, beforeBuildingIndexes, order); public void SetPropertyAttribute(Func attribute, Func when, - bool requiresIndex = true, + bool beforeBuildingIndexes = true, Order order = default - ) => conventions.SetPropertyAttribute((context, set) => set(context.Property, attribute(context)), when, requiresIndex, order); + ) => conventions.SetPropertyAttribute((context, set) => set(context.Property, attribute(context)), when, beforeBuildingIndexes, order); public void SetPropertyAttribute(Action> apply, Func when, - bool requiresIndex = true, + bool beforeBuildingIndexes = true, Order order = default - ) => conventions.Add(new SetAttributeConvention(apply, when, attributeRequiresIndex: requiresIndex), order); + ) => conventions.Add(new SetAttributeConvention(apply, when, beforeBuildingIndexes: beforeBuildingIndexes), order); public void AddPropertyAttribute(Func attribute, Func when, - bool requiresIndex = true, + bool beforeBuildingIndexes = true, Order order = default - ) => conventions.AddPropertyAttribute((context, add) => add(context.Property, attribute()), when, requiresIndex, order); + ) => conventions.AddPropertyAttribute((context, add) => add(context.Property, attribute()), when, beforeBuildingIndexes, order); public void AddPropertyAttribute(Func attribute, Func when, - bool requiresIndex = true, + bool beforeBuildingIndexes = true, Order order = default - ) => conventions.AddPropertyAttribute((context, add) => add(context.Property, attribute(context)), when, requiresIndex, order); + ) => conventions.AddPropertyAttribute((context, add) => add(context.Property, attribute(context)), when, beforeBuildingIndexes, order); public void AddPropertyAttribute(Action> apply, Func when, - bool requiresIndex = true, + bool beforeBuildingIndexes = true, Order order = default - ) => conventions.Add(new AddAttributeConvention(apply, when, attributeRequiresIndex: requiresIndex), order); + ) => conventions.Add(new AddAttributeConvention(apply, when, beforeBuildingIndexes: beforeBuildingIndexes), order); public void RemovePropertyAttribute(Func when, - bool requiresIndex = true, + bool beforeBuildingIndexes = true, Order order = default ) where TAttribute : Attribute => - conventions.Add(new RemoveAttributeConvention((context, remove) => remove(context.Property), when, attributeRequiresIndex: requiresIndex), order); + conventions.Add(new RemoveAttributeConvention((context, remove) => remove(context.Property), when, beforeBuildingIndexes: beforeBuildingIndexes), order); public void SetMethodAttribute(Func attribute, Func when, - bool requiresIndex = true, + bool beforeBuildingIndexes = true, Order order = default - ) => conventions.SetMethodAttribute((context, set) => set(context.Method, attribute()), when, requiresIndex, order); + ) => conventions.SetMethodAttribute((context, set) => set(context.Method, attribute()), when, beforeBuildingIndexes, order); public void SetMethodAttribute(Func attribute, Func when, - bool requiresIndex = true, + bool beforeBuildingIndexes = true, Order order = default - ) => conventions.SetMethodAttribute((context, set) => set(context.Method, attribute(context)), when, requiresIndex, order); + ) => conventions.SetMethodAttribute((context, set) => set(context.Method, attribute(context)), when, beforeBuildingIndexes, order); public void SetMethodAttribute(Action> apply, Func when, - bool requiresIndex = true, + bool beforeBuildingIndexes = true, Order order = default - ) => conventions.Add(new SetAttributeConvention(apply, when, attributeRequiresIndex: requiresIndex), order); + ) => conventions.Add(new SetAttributeConvention(apply, when, beforeBuildingIndexes: beforeBuildingIndexes), order); public void AddMethodAttribute(Func attribute, Func when, - bool requiresIndex = true, + bool beforeBuildingIndexes = true, Order order = default - ) => conventions.AddMethodAttribute((context, add) => add(context.Method, attribute()), when, requiresIndex, order); + ) => conventions.AddMethodAttribute((context, add) => add(context.Method, attribute()), when, beforeBuildingIndexes, order); public void AddMethodAttribute(Func attribute, Func when, - bool requiresIndex = true, + bool beforeBuildingIndexes = true, Order order = default - ) => conventions.AddMethodAttribute((context, add) => add(context.Method, attribute(context)), when, requiresIndex, order); + ) => conventions.AddMethodAttribute((context, add) => add(context.Method, attribute(context)), when, beforeBuildingIndexes, order); public void AddMethodAttribute(Action> apply, Func when, - bool requiresIndex = true, + bool beforeBuildingIndexes = true, Order order = default - ) => conventions.Add(new AddAttributeConvention(apply, when, attributeRequiresIndex: requiresIndex), order); + ) => conventions.Add(new AddAttributeConvention(apply, when, beforeBuildingIndexes: beforeBuildingIndexes), order); public void RemoveMethodAttribute(Func when, - bool requiresIndex = true, + bool beforeBuildingIndexes = true, Order order = default ) where TAttribute : Attribute => - conventions.Add(new RemoveAttributeConvention((context, remove) => remove(context.Method), when, attributeRequiresIndex: requiresIndex), order); + conventions.Add(new RemoveAttributeConvention((context, remove) => remove(context.Method), when, beforeBuildingIndexes: beforeBuildingIndexes), order); public void SetParameterAttribute(Func attribute, Func when, - bool requiresIndex = true, + bool beforeBuildingIndexes = true, Order order = default - ) => conventions.SetParameterAttribute((context, set) => set(context.Parameter, attribute()), when, requiresIndex, order); + ) => conventions.SetParameterAttribute((context, set) => set(context.Parameter, attribute()), when, beforeBuildingIndexes, order); public void SetParameterAttribute(Func attribute, Func when, - bool requiresIndex = true, + bool beforeBuildingIndexes = true, Order order = default - ) => conventions.SetParameterAttribute((context, set) => set(context.Parameter, attribute(context)), when, requiresIndex, order); + ) => conventions.SetParameterAttribute((context, set) => set(context.Parameter, attribute(context)), when, beforeBuildingIndexes, order); public void SetParameterAttribute(Action> apply, Func when, - bool requiresIndex = true, + bool beforeBuildingIndexes = true, Order order = default - ) => conventions.Add(new SetAttributeConvention(apply, when, attributeRequiresIndex: requiresIndex), order); + ) => conventions.Add(new SetAttributeConvention(apply, when, beforeBuildingIndexes: beforeBuildingIndexes), order); public void AddParameterAttribute(Func attribute, Func when, - bool requiresIndex = true, + bool beforeBuildingIndexes = true, Order order = default - ) => conventions.AddParameterAttribute((context, add) => add(context.Parameter, attribute()), when, requiresIndex, order); + ) => conventions.AddParameterAttribute((context, add) => add(context.Parameter, attribute()), when, beforeBuildingIndexes, order); public void AddParameterAttribute(Func attribute, Func when, - bool requiresIndex = true, + bool beforeBuildingIndexes = true, Order order = default - ) => conventions.AddParameterAttribute((context, add) => add(context.Parameter, attribute(context)), when, requiresIndex, order); + ) => conventions.AddParameterAttribute((context, add) => add(context.Parameter, attribute(context)), when, beforeBuildingIndexes, order); public void AddParameterAttribute(Action> apply, Func when, - bool requiresIndex = true, + bool beforeBuildingIndexes = true, Order order = default - ) => conventions.Add(new AddAttributeConvention(apply, when, attributeRequiresIndex: requiresIndex), order); + ) => conventions.Add(new AddAttributeConvention(apply, when, beforeBuildingIndexes: beforeBuildingIndexes), order); public void RemoveParameterAttribute(Func when, - bool requiresIndex = true, + bool beforeBuildingIndexes = true, Order order = default ) where TAttribute : Attribute => - conventions.Add(new RemoveAttributeConvention((context, remove) => remove(context.Parameter), when, attributeRequiresIndex: requiresIndex), order); + conventions.Add(new RemoveAttributeConvention((context, remove) => remove(context.Parameter), when, beforeBuildingIndexes: beforeBuildingIndexes), order); public void AddTypeAttributeConfiguration(Action attribute, Func when, // NOTE this is not optional to avoid ambiguous call when not given diff --git a/core/src/Baked/Monolith/MonolithRecipe.cs b/core/src/Baked/Monolith/MonolithRecipe.cs index 16553f6c8..1a6bf0aba 100644 --- a/core/src/Baked/Monolith/MonolithRecipe.cs +++ b/core/src/Baked/Monolith/MonolithRecipe.cs @@ -180,6 +180,7 @@ public override void Apply(ApplicationDescriptor app) { app.Layers.AddUi(); + app.Features.AddTheme(_theme); app.Features.AddUx( [ c => c.ActionsAsButtons(), @@ -199,8 +200,6 @@ public override void Apply(ApplicationDescriptor app) c => c.PropertiesAsFieldset(), c => c.RoutedTypesAsNavLinks() ]); - - app.Features.AddTheme(_theme); } _configure(app); diff --git a/core/src/Baked/Orm/AutoMap/AutoMapOrmFeature.cs b/core/src/Baked/Orm/AutoMap/AutoMapOrmFeature.cs index b050ab776..5538962a9 100644 --- a/core/src/Baked/Orm/AutoMap/AutoMapOrmFeature.cs +++ b/core/src/Baked/Orm/AutoMap/AutoMapOrmFeature.cs @@ -1,5 +1,6 @@ using Baked.Architecture; using Baked.Business; +using Baked.Domain.Configuration; using Baked.RestApi; using FluentNHibernate; using FluentNHibernate.Conventions.Helpers; @@ -44,7 +45,8 @@ public void Configure(LayerConfigurator configurator) when: c => c.Type.Has() && c.Property.IsAutoProperty, - attribute: () => new ColumnAttribute() + attribute: () => new ColumnAttribute(), + order: Order.At.Infra ); conventions.SetPropertyAttribute( when: c => @@ -52,7 +54,8 @@ public void Configure(LayerConfigurator configurator) c.Property.Has() && c.Property.PropertyType.TryGetMetadata(out var metadata) && metadata.Has(), - attribute: () => new ForeignKeyAttribute() + attribute: () => new ForeignKeyAttribute(), + order: Order.At.Infra ); }); diff --git a/core/src/Baked/RateLimiter/Concurrency/ConcurrencyRateLimiterFeature.cs b/core/src/Baked/RateLimiter/Concurrency/ConcurrencyRateLimiterFeature.cs index 64cc8b42a..a43edf145 100644 --- a/core/src/Baked/RateLimiter/Concurrency/ConcurrencyRateLimiterFeature.cs +++ b/core/src/Baked/RateLimiter/Concurrency/ConcurrencyRateLimiterFeature.cs @@ -1,4 +1,5 @@ using Baked.Architecture; +using Baked.Domain.Configuration; using Baked.RestApi.Model; using Baked.Runtime; using Microsoft.AspNetCore.Builder; @@ -16,8 +17,9 @@ public void Configure(LayerConfigurator configurator) { configurator.Domain.ConfigureConventions(conventions => { - conventions.AddMethodAttributeConfiguration(action => - action.AdditionalAttributes.Add("""EnableRateLimiting("Concurrency")""") + conventions.AddMethodAttributeConfiguration( + attribute: action => action.AdditionalAttributes.Add("""EnableRateLimiting("Concurrency")"""), + order: Order.At.Infra ); }); diff --git a/core/src/Baked/RestApi/RestApiExtensions.cs b/core/src/Baked/RestApi/RestApiExtensions.cs index a48a7d669..69af6c3a5 100644 --- a/core/src/Baked/RestApi/RestApiExtensions.cs +++ b/core/src/Baked/RestApi/RestApiExtensions.cs @@ -1,5 +1,6 @@ using Baked.Architecture; using Baked.Domain; +using Baked.Domain.Configuration; using Baked.RestApi; using Baked.RestApi.Conventions; using Baked.RestApi.Model; @@ -161,7 +162,7 @@ public void AddConfigureAction(string name, if (useRequestClassForBody is not null) { action.UseRequestClassForBody = useRequestClassForBody.Value; } if (parameter is not null) { parameter(action.Parameter); } }), - order: RestApiLayer.MinConventionOrder + 10 + order: Order.At.Infra.Min ); } @@ -182,7 +183,7 @@ public void AddOverrideAction(string name, if (useRequestClassForBody is not null) { action.UseRequestClassForBody = useRequestClassForBody.Value; } if (parameter is not null) { parameter(action.Parameter); } }), - order: RestApiLayer.MaxConventionOrder - 10 + order: Order.At.Override.Min ); } } diff --git a/core/src/Baked/RestApi/RestApiLayer.cs b/core/src/Baked/RestApi/RestApiLayer.cs index ba27f1060..80e5508f8 100644 --- a/core/src/Baked/RestApi/RestApiLayer.cs +++ b/core/src/Baked/RestApi/RestApiLayer.cs @@ -15,9 +15,6 @@ namespace Baked.RestApi; public class RestApiLayer : LayerBase { - public const int MinConventionOrder = -ConventionOrderLimit; - public const int MaxConventionOrder = ConventionOrderLimit; - readonly ApiModel _apiModel = new(); readonly IApplicationPartCollection _applicationParts = new ApplicationPartCollection(); readonly MvcNewtonsoftJsonOptions _mvcNewtonsoftJsonOptions = []; diff --git a/core/src/Baked/Theme/Default/DefaultThemeFeature.cs b/core/src/Baked/Theme/Default/DefaultThemeFeature.cs index bb13cc18d..bbf2406e6 100644 --- a/core/src/Baked/Theme/Default/DefaultThemeFeature.cs +++ b/core/src/Baked/Theme/Default/DefaultThemeFeature.cs @@ -1,6 +1,6 @@ using Baked.Architecture; using Baked.Business; -using Baked.RestApi; +using Baked.Domain.Configuration; using Baked.RestApi.Model; using Baked.Ui; using Humanizer; @@ -28,6 +28,12 @@ public virtual void Configure(LayerConfigurator configurator) builder.Index.Property.Add(); builder.Index.Method.Add(); builder.Index.Method.Add(); + + var index = builder.ConventionLevels.IndexOf("Override"); + if (index < 0) { index = builder.ConventionLevels.Count; } + + builder.ConventionLevels.Insert(index, nameof(Ux)); + builder.ConventionLevels.Insert(index, nameof(Theme)); }); configurator.Domain.ConfigureConventions(conventions => @@ -51,7 +57,8 @@ public virtual void Configure(LayerConfigurator configurator) var idAttribute = c.Type.GetMembers().FirstProperty().Get(); r.Params[idAttribute.RouteName] = idAttribute.RouteName; - } + }, + order: Order.At.Infra ); // Enum Data @@ -64,11 +71,12 @@ public virtual void Configure(LayerConfigurator configurator) conventions.SetPropertyAttribute( when: c => c.Property.IsPublic, attribute: c => new DataAttribute(c.Property.Name.Camelize()) { Label = c.Property.Name.Titleize() }, - order: -10 + order: Order.At.Infra - 10 ); conventions.AddPropertyAttributeConfiguration( when: c => c.Property.Has(), - attribute: data => data.Visible = false + attribute: data => data.Visible = false, + order: Order.At.Infra ); conventions.AddPropertyComponent( when: c => @@ -80,14 +88,14 @@ public virtual void Configure(LayerConfigurator configurator) metadata.Has() ), component: () => B.Text(), - order: UiLayer.MinConventionOrder + 10 + order: Order.At.Ux.Min ); // Method Defaults conventions.SetMethodAttribute( when: c => c.Method.Has(), attribute: () => new ActionAttribute(), - order: RestApiLayer.MaxConventionOrder + 10 + order: Order.At.Max ); conventions.AddMethodComponent( where: cc => cc.Path.Is(nameof(Page), "*", "*"), @@ -205,14 +213,14 @@ public virtual void Configure(LayerConfigurator configurator) c.Parameter.ParameterType.Is() || c.Parameter.ParameterType.SkipNullable().TryGetMetadata(out var metadata) && metadata.Has(), component: (c, cc) => ParameterInputText(c.Parameter, cc), - order: UiLayer.MinConventionOrder + 10 + order: Order.At.Ux.Min ); conventions.AddParameterComponent( when: c => c.Parameter.ParameterType.SkipNullable().Is() || c.Parameter.ParameterType.SkipNullable().Is(), component: (c, cc) => ParameterInputNumber(c.Parameter, cc), - order: UiLayer.MinConventionOrder + 10 + order: Order.At.Ux.Min ); // `PageTitle` defaults @@ -276,7 +284,7 @@ public virtual void Configure(LayerConfigurator configurator) sb.LabelNone(); }, - order: UiLayer.MaxConventionOrder - 10 + order: Order.At.Max ); }); diff --git a/core/src/Baked/Theme/ThemeExtensions.cs b/core/src/Baked/Theme/ThemeExtensions.cs index c8bae5e96..e3d1d1946 100644 --- a/core/src/Baked/Theme/ThemeExtensions.cs +++ b/core/src/Baked/Theme/ThemeExtensions.cs @@ -4,7 +4,6 @@ using Baked.Domain.Configuration; using Baked.Domain.Inspection; using Baked.Domain.Model; -using Baked.RestApi; using Baked.RestApi.Model; using Baked.Testing; using Baked.Theme; @@ -112,6 +111,20 @@ public Route ChildDynamic(string path, string title, string parentPath) => router.Create(path, title) with { ParentPath = parentPath, ErrorSafeLink = false, SideMenu = false }; } + extension(Order order) + { + public Order Theme => + order.Level(nameof(Theme)); + + public Order Ux => + order.Level(nameof(Ux)); + +#pragma warning disable IDE0051 + Order ThemeDefault => + order.Level(nameof(Theme), @default: true); +#pragma warning restore IDE0051 + } + extension(IDomainModelConventionCollection conventions) { public void AddEntityRemoteData() @@ -128,7 +141,8 @@ public void AddEntityRemoteData() } return Remote(locate.GetRoute(), o => o.Params = Computed.UseRoute("params")); - } + }, + order: Order.At.Override ); } @@ -162,7 +176,7 @@ public void AddTypeSchema(Func true; where ??= c => true; - order += RestApiLayer.MaxConventionOrder + LayerBase.ConventionOrderLimit; + order = order.ThemeDefault; conventions.AddTypeAttribute( attribute: c => new GeneratorAttribute @@ -172,7 +186,7 @@ public void AddTypeSchema(Func(Func when, Order order = default ) { - order += RestApiLayer.MaxConventionOrder + LayerBase.ConventionOrderLimit; + order = order.ThemeDefault; conventions.RemoveTypeAttribute>(when: when, - requiresIndex: false, + beforeBuildingIndexes: false, order: order ); } @@ -219,7 +233,7 @@ public void AddPropertySchema(Func true; where ??= c => true; - order += RestApiLayer.MaxConventionOrder + LayerBase.ConventionOrderLimit; + order = order.ThemeDefault; conventions.AddPropertyAttribute( attribute: c => new GeneratorAttribute @@ -229,7 +243,7 @@ public void AddPropertySchema(Func(Func when, Order order = default ) { - order += RestApiLayer.MaxConventionOrder + LayerBase.ConventionOrderLimit; + order = order.ThemeDefault; conventions.RemovePropertyAttribute>(when: when, - requiresIndex: false, + beforeBuildingIndexes: false, order: order ); } @@ -276,7 +290,7 @@ public void AddMethodSchema(Func true; where ??= c => true; - order += RestApiLayer.MaxConventionOrder + LayerBase.ConventionOrderLimit; + order = order.ThemeDefault; conventions.AddMethodAttribute( attribute: c => new GeneratorAttribute @@ -286,7 +300,7 @@ public void AddMethodSchema(Func c.Type.Has() && c.Method.Has() && when(c), - requiresIndex: false, + beforeBuildingIndexes: false, order: order ); } @@ -295,10 +309,10 @@ public void RemoveMethodSchema(Func when, Order order = default ) { - order += RestApiLayer.MaxConventionOrder + LayerBase.ConventionOrderLimit; + order = order.ThemeDefault; conventions.RemoveMethodAttribute>(when: when, - requiresIndex: false, + beforeBuildingIndexes: false, order: order ); } @@ -333,7 +347,7 @@ public void AddParameterSchema(Func true; where ??= c => true; - order += RestApiLayer.MaxConventionOrder + LayerBase.ConventionOrderLimit; + order = order.ThemeDefault; conventions.AddParameterAttribute( attribute: c => new GeneratorAttribute @@ -343,7 +357,7 @@ public void AddParameterSchema(Func c.Type.Has() && c.Parameter.Has() && when(c), - requiresIndex: false, + beforeBuildingIndexes: false, order: order ); } @@ -352,10 +366,10 @@ public void RemoveParameterSchema(Func whe Order order = default ) { - order += RestApiLayer.MaxConventionOrder + LayerBase.ConventionOrderLimit; + order = order.ThemeDefault; conventions.RemoveParameterAttribute>(when: when, - requiresIndex: false, + beforeBuildingIndexes: false, order: order ); } @@ -388,7 +402,7 @@ public void AddTypeSchemaConfiguration(Action true; where ??= _ => true; - order += RestApiLayer.MaxConventionOrder + LayerBase.ConventionOrderLimit * 2; + order = order.ThemeDefault; conventions.AddTypeAttributeConfiguration>( attribute: (attribute, c) => attribute.WrapGenerator( @@ -429,7 +443,7 @@ public void AddPropertySchemaConfiguration(Action true; where ??= _ => true; - order += RestApiLayer.MaxConventionOrder + LayerBase.ConventionOrderLimit * 2; + order = order.ThemeDefault; conventions.AddPropertyAttributeConfiguration>( attribute: (attribute, c) => attribute.WrapGenerator( @@ -470,7 +484,7 @@ public void AddMethodSchemaConfiguration(Action true; where ??= _ => true; - order += RestApiLayer.MaxConventionOrder + LayerBase.ConventionOrderLimit * 2; + order = order.ThemeDefault; conventions.AddMethodAttributeConfiguration>( attribute: (attribute, c) => attribute.WrapGenerator( @@ -511,7 +525,7 @@ public void AddParameterSchemaConfiguration(Action true; where ??= _ => true; - order += RestApiLayer.MaxConventionOrder + LayerBase.ConventionOrderLimit * 2; + order = order.ThemeDefault; conventions.AddParameterAttributeConfiguration>( attribute: (attribute, c) => attribute.WrapGenerator( @@ -556,7 +570,7 @@ public void AddTypeComponent(Func true; where ??= c => true; - order += RestApiLayer.MaxConventionOrder + LayerBase.ConventionOrderLimit; + order = order.ThemeDefault; conventions.AddTypeAttribute( apply: (c, add) => @@ -573,7 +587,7 @@ public void AddTypeComponent(Func when(c), - requiresIndex: false, + beforeBuildingIndexes: false, order: order ); } @@ -582,10 +596,10 @@ public void RemoveTypeComponent(Func wh Order order = default ) where TSchema : IComponentSchema { - order += RestApiLayer.MaxConventionOrder + LayerBase.ConventionOrderLimit; + order = order.ThemeDefault; conventions.RemoveTypeAttribute>(when, - requiresIndex: false, + beforeBuildingIndexes: false, order: order ); } @@ -622,7 +636,7 @@ public void AddPropertyComponent(Func true; where ??= c => true; - order += RestApiLayer.MaxConventionOrder + LayerBase.ConventionOrderLimit; + order = order.ThemeDefault; conventions.AddPropertyAttribute( apply: (c, add) => @@ -639,7 +653,7 @@ public void AddPropertyComponent(Func when(c), - requiresIndex: false, + beforeBuildingIndexes: false, order: order ); } @@ -648,10 +662,10 @@ public void RemovePropertyComponent(Func wh Order order = default ) where TSchema : IComponentSchema { - order += RestApiLayer.MaxConventionOrder + LayerBase.ConventionOrderLimit; + order = order.ThemeDefault; conventions.RemovePropertyAttribute>(when, - requiresIndex: false, + beforeBuildingIndexes: false, order: order ); } @@ -688,7 +702,7 @@ public void AddMethodComponent(Func true; where ??= cc => true; - order += RestApiLayer.MaxConventionOrder + LayerBase.ConventionOrderLimit; + order = order.ThemeDefault; conventions.AddMethodAttribute( apply: (c, add) => @@ -705,7 +719,7 @@ public void AddMethodComponent(Func c.Type.Has() && c.Method.Has() && when(c), - requiresIndex: false, + beforeBuildingIndexes: false, order: order ); } @@ -714,10 +728,10 @@ public void RemoveMethodComponent(Func when, Order order = default ) where TSchema : IComponentSchema { - order += RestApiLayer.MaxConventionOrder + LayerBase.ConventionOrderLimit; + order = order.ThemeDefault; conventions.RemoveMethodAttribute>(when, - requiresIndex: false, + beforeBuildingIndexes: false, order: order ); } @@ -754,7 +768,7 @@ public void AddParameterComponent(Func true; where ??= c => true; - order += RestApiLayer.MaxConventionOrder + LayerBase.ConventionOrderLimit; + order = order.ThemeDefault; conventions.AddParameterAttribute( apply: (c, add) => @@ -771,7 +785,7 @@ public void AddParameterComponent(Func c.Type.Has() && c.Parameter.Has() && when(c), - requiresIndex: false, + beforeBuildingIndexes: false, order: order ); } @@ -780,10 +794,10 @@ public void RemoveParameterComponent(Func Order order = default ) where TSchema : IComponentSchema { - order += RestApiLayer.MaxConventionOrder + LayerBase.ConventionOrderLimit; + order = order.ThemeDefault; conventions.RemoveParameterAttribute>(when, - requiresIndex: false, + beforeBuildingIndexes: false, order: order ); } @@ -818,7 +832,7 @@ public void AddTypeComponentConfiguration(Action true; where ??= _ => true; - order += RestApiLayer.MaxConventionOrder + LayerBase.ConventionOrderLimit * 2; + order = order.ThemeDefault; conventions.AddTypeAttributeConfiguration>( attribute: (attribute, c) => attribute.WrapGenerator( @@ -861,7 +875,7 @@ public void AddPropertyComponentConfiguration(Action true; where ??= _ => true; - order += RestApiLayer.MaxConventionOrder + LayerBase.ConventionOrderLimit * 2; + order = order.ThemeDefault; conventions.AddPropertyAttributeConfiguration>( attribute: (attribute, c) => attribute.WrapGenerator( @@ -904,7 +918,7 @@ public void AddMethodComponentConfiguration(Action true; where ??= _ => true; - order += RestApiLayer.MaxConventionOrder + LayerBase.ConventionOrderLimit * 2; + order = order.ThemeDefault; conventions.AddMethodAttributeConfiguration>( attribute: (attribute, c) => attribute.WrapGenerator( @@ -947,7 +961,7 @@ public void AddParameterComponentConfiguration(Action true; where ??= _ => true; - order += RestApiLayer.MaxConventionOrder + LayerBase.ConventionOrderLimit * 2; + order = order.ThemeDefault; conventions.AddParameterAttributeConfiguration>( attribute: (attribute, c) => attribute.WrapGenerator( diff --git a/core/src/Baked/Ui/UiLayer.cs b/core/src/Baked/Ui/UiLayer.cs index db9b93329..ff81c354c 100644 --- a/core/src/Baked/Ui/UiLayer.cs +++ b/core/src/Baked/Ui/UiLayer.cs @@ -11,9 +11,6 @@ namespace Baked.Ui; public class UiLayer : LayerBase { - public const int MinConventionOrder = -ConventionOrderLimit; - public const int MaxConventionOrder = ConventionOrderLimit; - static bool NoUi => Environment.GetCommandLineArgs().Contains("--no-ui"); static JsonSerializerSettings JsonSettings { get; } = new() { diff --git a/core/src/Baked/Ux/ActionsAreContents/ActionsAreContentsUxFeature.cs b/core/src/Baked/Ux/ActionsAreContents/ActionsAreContentsUxFeature.cs index 26268df96..66a9d60e7 100644 --- a/core/src/Baked/Ux/ActionsAreContents/ActionsAreContentsUxFeature.cs +++ b/core/src/Baked/Ux/ActionsAreContents/ActionsAreContentsUxFeature.cs @@ -1,5 +1,6 @@ using Baked.Architecture; using Baked.Business; +using Baked.Domain.Configuration; using Baked.RestApi.Model; using Baked.Ui; using Humanizer; @@ -33,7 +34,8 @@ public void Configure(LayerConfigurator configurator) sp.Schema.Contents.Add(content); } - } + }, + order: Order.At.Ux ); conventions.AddTypeComponentConfiguration( when: c => @@ -65,7 +67,7 @@ public void Configure(LayerConfigurator configurator) tp.Schema.Tabs.AddRange(tabs.Values); }, - order: -10 + order: Order.At.Ux - 10 ); conventions.AddTypeComponentConfiguration( component: (tp, c, cc) => @@ -78,7 +80,8 @@ public void Configure(LayerConfigurator configurator) { tab.Title = l(tab.Id.Replace("-", "_").Titleize()); } - } + }, + order: Order.At.Ux ); }); } diff --git a/core/src/Baked/Ux/ActionsAsButtons/ActionsAsButtonsUxFeature.cs b/core/src/Baked/Ux/ActionsAsButtons/ActionsAsButtonsUxFeature.cs index ae95fbb32..60a92849a 100644 --- a/core/src/Baked/Ux/ActionsAsButtons/ActionsAsButtonsUxFeature.cs +++ b/core/src/Baked/Ux/ActionsAsButtons/ActionsAsButtonsUxFeature.cs @@ -1,4 +1,5 @@ using Baked.Architecture; +using Baked.Domain.Configuration; using Baked.RestApi; using Baked.Theme; using Baked.Theme.Default; @@ -20,7 +21,8 @@ public void Configure(LayerConfigurator configurator) conventions.AddMethodComponent( when: c => c.Method.Has() && !c.Method.DefaultOverload.Parameters.Any(), where: cc => cc.Path.EndsWith("Actions", "*"), - component: (c, cc) => MethodButton(c.Method, cc) + component: (c, cc) => MethodButton(c.Method, cc), + order: Order.At.Ux ); // `SimpleForm` with dialog options @@ -32,11 +34,13 @@ public void Configure(LayerConfigurator configurator) c.Method.GetAction().Method == HttpMethod.Delete ), where: cc => cc.Path.EndsWith("Actions", "*"), - component: (c, cc) => MethodSimpleForm(c.Method, cc) + component: (c, cc) => MethodSimpleForm(c.Method, cc), + order: Order.At.Ux ); conventions.AddMethodSchema( where: cc => cc.Path.EndsWith("Actions", "*", nameof(SimpleForm), nameof(SimpleForm.DialogOptions)), - schema: (c, cc) => MethodSimpleFormDialog(c.Method, cc) + schema: (c, cc) => MethodSimpleFormDialog(c.Method, cc), + order: Order.At.Ux ); conventions.AddMethodSchemaConfiguration( when: c => !c.Method.DefaultOverload.Parameters.Any(), @@ -45,7 +49,8 @@ public void Configure(LayerConfigurator configurator) var (_, l) = cc; sfd.Message = l("Are you sure?"); - } + }, + order: Order.At.Ux ); // Routed button and routing back @@ -59,7 +64,8 @@ public void Configure(LayerConfigurator configurator) return LocalizedButton(c.Method.Name.Titleize(), cc, action: Local.UseRedirect(route) ); - } + }, + order: Order.At.Ux ); conventions.AddMethodSchemaConfiguration( when: c => c.Method.TryGet(out var action) && action.RoutePathBack is not null, @@ -73,29 +79,34 @@ public void Configure(LayerConfigurator configurator) ); ra.PostAction = Local.UseRedirect(routeBack); - } + }, + order: Order.At.Ux ); // Open button (for dialog) conventions.AddMethodComponent( where: cc => cc.Path.EndsWith(nameof(SimpleForm.DialogOptions), nameof(SimpleForm.DialogOptions.Open)), - component: (c, cc) => LocalizedButton(c.Method.Name.Titleize(), cc) + component: (c, cc) => LocalizedButton(c.Method.Name.Titleize(), cc), + order: Order.At.Ux ); // Submit button (for dialog and page) conventions.AddMethodComponent( when: c => c.Method.Has(), where: cc => cc.Path.EndsWith("Submit"), - component: (c, cc) => LocalizedButton(c.Method.Name.Titleize(), cc) + component: (c, cc) => LocalizedButton(c.Method.Name.Titleize(), cc), + order: Order.At.Ux ); conventions.AddMethodComponentConfiguration