From 698238e2d55679e4823ad1e1faae88f70efff05e Mon Sep 17 00:00:00 2001 From: Felix-CodingClimber Date: Thu, 11 Jan 2024 15:40:58 +0100 Subject: [PATCH 1/2] Improved database concurrency checks --- .../20240102133036_InitialCreate.Designer.cs | 109 ------------------ ...240105214249_AddedEntityVersionProperty.cs | 41 ------- ... 20240110205937_InitialCreate.Designer.cs} | 44 +++---- ...ate.cs => 20240110205937_InitialCreate.cs} | 4 +- .../Migrations/AppDbContextModelSnapshot.cs | 40 +++---- samples/DotNetElements.CrudExample/Program.cs | 3 +- samples/DotNetElements.CrudExample/TestDb.db | Bin 40960 -> 40960 bytes .../DotNetElements.CrudExample/TestDb.db-shm | Bin 32768 -> 32768 bytes .../DotNetElements.CrudExample/TestDb.db-wal | Bin 0 -> 12392 bytes src/DotNetElements.Core/Core/EntityBase.cs | 9 -- .../Extensions/ServiceCollectionExtensions.cs | 14 +-- src/DotNetElements.Core/Core/IHasVersion.cs | 20 ++++ src/DotNetElements.Core/Core/ModelBase.cs | 2 +- src/DotNetElements.Core/Core/Repository.cs | 19 +++ website/docusaurus.config.ts | 2 +- 15 files changed, 95 insertions(+), 212 deletions(-) delete mode 100644 samples/DotNetElements.CrudExample/Migrations/20240102133036_InitialCreate.Designer.cs delete mode 100644 samples/DotNetElements.CrudExample/Migrations/20240105214249_AddedEntityVersionProperty.cs rename samples/DotNetElements.CrudExample/Migrations/{20240105214249_AddedEntityVersionProperty.Designer.cs => 20240110205937_InitialCreate.Designer.cs} (87%) rename samples/DotNetElements.CrudExample/Migrations/{20240102133036_InitialCreate.cs => 20240110205937_InitialCreate.cs} (94%) create mode 100644 src/DotNetElements.Core/Core/IHasVersion.cs diff --git a/samples/DotNetElements.CrudExample/Migrations/20240102133036_InitialCreate.Designer.cs b/samples/DotNetElements.CrudExample/Migrations/20240102133036_InitialCreate.Designer.cs deleted file mode 100644 index 9d76d74..0000000 --- a/samples/DotNetElements.CrudExample/Migrations/20240102133036_InitialCreate.Designer.cs +++ /dev/null @@ -1,109 +0,0 @@ -// -using System; -using DotNetElements.Datahandling; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; - -#nullable disable - -namespace DotNetElements.Migrations -{ - [DbContext(typeof(AppDbContext))] - [Migration("20240102133036_InitialCreate")] - partial class InitialCreate - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder.HasAnnotation("ProductVersion", "8.0.0"); - - modelBuilder.Entity("BlazorCrud.Modules.BlogPostModule.BlogPost", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("TEXT"); - - b.Property("CreationTime") - .HasColumnType("TEXT"); - - b.Property("CreatorId") - .HasColumnType("TEXT"); - - b.Property("LastModificationTime") - .HasColumnType("TEXT"); - - b.Property("LastModifierId") - .HasColumnType("TEXT"); - - b.Property("Title") - .IsRequired() - .HasColumnType("nvarchar(256)"); - - b.HasKey("Id"); - - b.ToTable("BlogPosts"); - }); - - modelBuilder.Entity("BlazorCrud.Modules.TagModule.Tag", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("TEXT"); - - b.Property("CreationTime") - .HasColumnType("TEXT"); - - b.Property("CreatorId") - .HasColumnType("TEXT"); - - b.Property("Label") - .IsRequired() - .HasColumnType("nvarchar(256)"); - - b.Property("LastModificationTime") - .HasColumnType("TEXT"); - - b.Property("LastModifierId") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.ToTable("Tags"); - }); - - modelBuilder.Entity("BlogPostTag", b => - { - b.Property("BlogPostsId") - .HasColumnType("TEXT"); - - b.Property("TagsId") - .HasColumnType("TEXT"); - - b.HasKey("BlogPostsId", "TagsId"); - - b.HasIndex("TagsId"); - - b.ToTable("BlogPostTag"); - }); - - modelBuilder.Entity("BlogPostTag", b => - { - b.HasOne("BlazorCrud.Modules.BlogPostModule.BlogPost", null) - .WithMany() - .HasForeignKey("BlogPostsId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("BlazorCrud.Modules.TagModule.Tag", null) - .WithMany() - .HasForeignKey("TagsId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/samples/DotNetElements.CrudExample/Migrations/20240105214249_AddedEntityVersionProperty.cs b/samples/DotNetElements.CrudExample/Migrations/20240105214249_AddedEntityVersionProperty.cs deleted file mode 100644 index c4ebb85..0000000 --- a/samples/DotNetElements.CrudExample/Migrations/20240105214249_AddedEntityVersionProperty.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace DotNetElements.Migrations -{ - /// - public partial class AddedEntityVersionProperty : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn( - name: "Version", - table: "Tags", - type: "TEXT", - nullable: false, - defaultValue: new Guid("00000000-0000-0000-0000-000000000000")); - - migrationBuilder.AddColumn( - name: "Version", - table: "BlogPosts", - type: "TEXT", - nullable: false, - defaultValue: new Guid("00000000-0000-0000-0000-000000000000")); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropColumn( - name: "Version", - table: "Tags"); - - migrationBuilder.DropColumn( - name: "Version", - table: "BlogPosts"); - } - } -} diff --git a/samples/DotNetElements.CrudExample/Migrations/20240105214249_AddedEntityVersionProperty.Designer.cs b/samples/DotNetElements.CrudExample/Migrations/20240110205937_InitialCreate.Designer.cs similarity index 87% rename from samples/DotNetElements.CrudExample/Migrations/20240105214249_AddedEntityVersionProperty.Designer.cs rename to samples/DotNetElements.CrudExample/Migrations/20240110205937_InitialCreate.Designer.cs index 7493884..4cfd0bf 100644 --- a/samples/DotNetElements.CrudExample/Migrations/20240105214249_AddedEntityVersionProperty.Designer.cs +++ b/samples/DotNetElements.CrudExample/Migrations/20240110205937_InitialCreate.Designer.cs @@ -8,11 +8,11 @@ #nullable disable -namespace DotNetElements.Migrations +namespace DotNetElements.CrudExample.Migrations { [DbContext(typeof(AppDbContext))] - [Migration("20240105214249_AddedEntityVersionProperty")] - partial class AddedEntityVersionProperty + [Migration("20240110205937_InitialCreate")] + partial class InitialCreate { /// protected override void BuildTargetModel(ModelBuilder modelBuilder) @@ -20,7 +20,22 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) #pragma warning disable 612, 618 modelBuilder.HasAnnotation("ProductVersion", "8.0.0"); - modelBuilder.Entity("BlazorCrud.Modules.BlogPostModule.BlogPost", b => + modelBuilder.Entity("BlogPostTag", b => + { + b.Property("BlogPostsId") + .HasColumnType("TEXT"); + + b.Property("TagsId") + .HasColumnType("TEXT"); + + b.HasKey("BlogPostsId", "TagsId"); + + b.HasIndex("TagsId"); + + b.ToTable("BlogPostTag"); + }); + + modelBuilder.Entity("DotNetElements.CrudExample.Modules.BlogPostModule.BlogPost", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -51,7 +66,7 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.ToTable("BlogPosts"); }); - modelBuilder.Entity("BlazorCrud.Modules.TagModule.Tag", b => + modelBuilder.Entity("DotNetElements.CrudExample.Modules.TagModule.Tag", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -84,28 +99,13 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) modelBuilder.Entity("BlogPostTag", b => { - b.Property("BlogPostsId") - .HasColumnType("TEXT"); - - b.Property("TagsId") - .HasColumnType("TEXT"); - - b.HasKey("BlogPostsId", "TagsId"); - - b.HasIndex("TagsId"); - - b.ToTable("BlogPostTag"); - }); - - modelBuilder.Entity("BlogPostTag", b => - { - b.HasOne("BlazorCrud.Modules.BlogPostModule.BlogPost", null) + b.HasOne("DotNetElements.CrudExample.Modules.BlogPostModule.BlogPost", null) .WithMany() .HasForeignKey("BlogPostsId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.HasOne("BlazorCrud.Modules.TagModule.Tag", null) + b.HasOne("DotNetElements.CrudExample.Modules.TagModule.Tag", null) .WithMany() .HasForeignKey("TagsId") .OnDelete(DeleteBehavior.Cascade) diff --git a/samples/DotNetElements.CrudExample/Migrations/20240102133036_InitialCreate.cs b/samples/DotNetElements.CrudExample/Migrations/20240110205937_InitialCreate.cs similarity index 94% rename from samples/DotNetElements.CrudExample/Migrations/20240102133036_InitialCreate.cs rename to samples/DotNetElements.CrudExample/Migrations/20240110205937_InitialCreate.cs index 7e62f0b..0f8d551 100644 --- a/samples/DotNetElements.CrudExample/Migrations/20240102133036_InitialCreate.cs +++ b/samples/DotNetElements.CrudExample/Migrations/20240110205937_InitialCreate.cs @@ -3,7 +3,7 @@ #nullable disable -namespace DotNetElements.Migrations +namespace DotNetElements.CrudExample.Migrations { /// public partial class InitialCreate : Migration @@ -17,6 +17,7 @@ protected override void Up(MigrationBuilder migrationBuilder) { Id = table.Column(type: "TEXT", nullable: false), Title = table.Column(type: "nvarchar(256)", nullable: false), + Version = table.Column(type: "TEXT", nullable: false), CreatorId = table.Column(type: "TEXT", nullable: false), CreationTime = table.Column(type: "TEXT", nullable: false), LastModifierId = table.Column(type: "TEXT", nullable: true), @@ -33,6 +34,7 @@ protected override void Up(MigrationBuilder migrationBuilder) { Id = table.Column(type: "TEXT", nullable: false), Label = table.Column(type: "nvarchar(256)", nullable: false), + Version = table.Column(type: "TEXT", nullable: false), CreatorId = table.Column(type: "TEXT", nullable: false), CreationTime = table.Column(type: "TEXT", nullable: false), LastModifierId = table.Column(type: "TEXT", nullable: true), diff --git a/samples/DotNetElements.CrudExample/Migrations/AppDbContextModelSnapshot.cs b/samples/DotNetElements.CrudExample/Migrations/AppDbContextModelSnapshot.cs index 1cabfec..fd6dfc6 100644 --- a/samples/DotNetElements.CrudExample/Migrations/AppDbContextModelSnapshot.cs +++ b/samples/DotNetElements.CrudExample/Migrations/AppDbContextModelSnapshot.cs @@ -7,7 +7,7 @@ #nullable disable -namespace DotNetElements.Migrations +namespace DotNetElements.CrudExample.Migrations { [DbContext(typeof(AppDbContext))] partial class AppDbContextModelSnapshot : ModelSnapshot @@ -17,7 +17,22 @@ protected override void BuildModel(ModelBuilder modelBuilder) #pragma warning disable 612, 618 modelBuilder.HasAnnotation("ProductVersion", "8.0.0"); - modelBuilder.Entity("BlazorCrud.Modules.BlogPostModule.BlogPost", b => + modelBuilder.Entity("BlogPostTag", b => + { + b.Property("BlogPostsId") + .HasColumnType("TEXT"); + + b.Property("TagsId") + .HasColumnType("TEXT"); + + b.HasKey("BlogPostsId", "TagsId"); + + b.HasIndex("TagsId"); + + b.ToTable("BlogPostTag"); + }); + + modelBuilder.Entity("DotNetElements.CrudExample.Modules.BlogPostModule.BlogPost", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -48,7 +63,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("BlogPosts"); }); - modelBuilder.Entity("BlazorCrud.Modules.TagModule.Tag", b => + modelBuilder.Entity("DotNetElements.CrudExample.Modules.TagModule.Tag", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -81,28 +96,13 @@ protected override void BuildModel(ModelBuilder modelBuilder) modelBuilder.Entity("BlogPostTag", b => { - b.Property("BlogPostsId") - .HasColumnType("TEXT"); - - b.Property("TagsId") - .HasColumnType("TEXT"); - - b.HasKey("BlogPostsId", "TagsId"); - - b.HasIndex("TagsId"); - - b.ToTable("BlogPostTag"); - }); - - modelBuilder.Entity("BlogPostTag", b => - { - b.HasOne("BlazorCrud.Modules.BlogPostModule.BlogPost", null) + b.HasOne("DotNetElements.CrudExample.Modules.BlogPostModule.BlogPost", null) .WithMany() .HasForeignKey("BlogPostsId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.HasOne("BlazorCrud.Modules.TagModule.Tag", null) + b.HasOne("DotNetElements.CrudExample.Modules.TagModule.Tag", null) .WithMany() .HasForeignKey("TagsId") .OnDelete(DeleteBehavior.Cascade) diff --git a/samples/DotNetElements.CrudExample/Program.cs b/samples/DotNetElements.CrudExample/Program.cs index 14ff20d..d6256bc 100644 --- a/samples/DotNetElements.CrudExample/Program.cs +++ b/samples/DotNetElements.CrudExample/Program.cs @@ -1,6 +1,7 @@ using DotNetElements.Datahandling; using MudBlazor.Services; using DotNetElements.CrudExample.Components; +using DotNetElements.CrudExample.Modules.BlogPostModule; var builder = WebApplication.CreateBuilder(args); @@ -18,7 +19,7 @@ builder.Services.AddDatabaseMigrationService(); builder.AddSettings(); -builder.Services.RegisterModules(); +builder.Services.RegisterModules(typeof(BlogPostModule).Assembly); var app = builder.Build(); diff --git a/samples/DotNetElements.CrudExample/TestDb.db b/samples/DotNetElements.CrudExample/TestDb.db index ba6941b9c65d8b07563dd659befeb6f62d4faf15..5b3afd08487a77ab8e0eee27cb80508a5cf93e07 100644 GIT binary patch delta 965 zcmb`F&1(}u7{+IJZIex#9b+g#JZyxB(ssgp?N=^wce6{Sg%-)ygJ1}fmPl!!%^%Q| zdhk@sp4EeR@E{fTTA?=&-aJV`D0maZiw8Yu-8E^cp7!9tzzpxhZ=UCUXX{YhIusvY zDTn}oT)a=$*xoEtMNnP&oQL0mEbjv4J$#jKD$gdq`M>06AN}l|;s <+wZp5+>K7V z-^s_J1Xu*H7(15X{lNnv8=xRq3>GOf4aZ{?QQc>VV@#2yyBHCJSUS;6!*k4LXR}{+ z)_SYurCxj@hT{|8VLoC6JBag!jZ9)EC*RXF*QdJXhxOL%WrE9;)G)3Qy~-&g%%U^# z4dbMGX;h^(!m3nfn$Dsh^-mC|v6Lhdl>-3pDF<<;*NQbz#cXgj&IEwQe9dZjE^@Jn z5jQDEmSu3{I1Sq}b&NHl{mIm9ua;@}Laro!Zl8C{sD&-f9J(E-al3|S-==zlI6iVc zY9elP9of_|k!BFb^Ek6~iqFvG6n*VHnqZw9#t5DKI1%mxxDP+X<9rV9-jD(zO#tz_ w6v%1p42K^97{w2~gm>lzDG1W^I1N1UFTgYS!or0hkpB}rI;nqzl{7AX12O64@Bjb+ literal 40960 zcmeI)&u`mQ00(e8PLno}nM)PzRFfjL5p(hLkJv6q;3PIgO_P!)s5^`(Tig-UHIR6S z?Y6P)#Q(sN6Ph&s3dD^Ih!bb-liTsNbhJcI@Z(o%0SG_<0uZD@l)4T8aV zB3`V!PQ#TNPNCvT+420Ww4F{#G-S)2tkiIi8d9}Jhi0WB6>HVQM%^h_8&dXQuQj#K zLA|{1)UQi>?)7V<)f?U5#Lr5nU$y(UK5O^4RU@ApCly92_WgFy>z~VNW_h=F+UVY) zY0Z=-j8bV2g8g2nd))P>(xJsYAK_Lzm`jUBOQ)_$*-!lbfG(QLLMpkQ)2uY4EoBsB zHlBM6mu=-9e!7y(tgrKrH-_kq_U!>160_87)(a?~MPC41Y2WluE*J2fwPeQJ{&|L+&AwflbOv; z{>l3@2N7L7mCNev-kn-9*~#HdTE4j|7FNt<~Xnj53){ z$D16!G}hR0FqvXS^=fsu{9%_ZpcigZ07R((y5%Wn#hzld2U!)249}gyMR{vZqOTk9&aeyd=kRZ z4{PZ@f0Z4@k3<~Bqxv{JP3E=|iOjp}%RJfcXc6|F6#wF7cJX<%Idk0L;xl_8J5wd` zM8@4%rW#gEN;{rhd2qzj^PtH;tPOozE!W%c-tG^tZiA1y1A0Zhw{T``_FT0v&g85$ zPV?MZYyO+Sl7yyCPT_g(px^7SBWC&P{fe;A8(@W;ewocITQLx2DT zAOHafKmY;|fB*y_009U<;1v;&g%%&VB_OsTxND=>3mXAg|35F99DN}`00Izz00bZa z0SG_<0uX=z1RyXg@WA7f&3Br$W=(fVNiSFhx#TI1tmh3=ww;14Yf8~mG@|DVw%PCp zfy92HAhDkrN~+>{x@Q`8QC4h{rz;U6+l73du9P=)%`r$pb=Y0ItPokzCB@t&)-F+Z z6w@Y(WxTB@yUL3tVn{Rv&Dd4-9aGZ`O}EbyVg3KS_!~!G2oQh(1Rwwb2tWV=5P$## zAOHaf{Lciogyve5rU};nFI@SS6Ca7Ibc6r_2tWV=5P$##AOHafKmY;|xNw2{LbCa0 zv&M0{>bXVF(d2@sxU_p*H)OkL=ya+?T*oSvET=f^Q>TBZC}}UznQreAbH}zU-O{wP ze(?LTQQoFz>uSMuWY2PF-o(^p%W`em(j3PqD*2L4)N$VGOXN*E@(InGSeiBJgTGIo zB^YkEMYmMf^14i{yejKOl|D;Aw^(*OJ5LP5v6NDNoHu#dyiHBlRnwaE{|n+1PJALh z#WMgGUd53C1Rwwb2tWV=5P$##AOHafTxx-Bp~**S^blCYC@mB**8d-+IbqoUFJ9%u ztKyI1@ul7g*mwv)00Izz00bZa0SG_<0uZ>20(*kcY({y4KFWRj-b%#8qTI6Y#Umyb zrJ*1t`tc diff --git a/samples/DotNetElements.CrudExample/TestDb.db-shm b/samples/DotNetElements.CrudExample/TestDb.db-shm index fe9ac2845eca6fe6da8a63cd096d9cf9e24ece10..9e2a72b55cbae60a81338fdf466de9141ef90d78 100644 GIT binary patch delta 167 zcmZo@U}|V!s+V}A%K!q55G=q9q`82&Wcr5b>A~_Zj=$JDVYYXQX-83*o`R{LIjQP_ kMu7py-2X@bDlEjn1ZA-RX)xZ{nC{KW2oz`D*vM=G0QATzO8@`> delta 89 zcmZo@U}|V!;+1%$%K!t66DLZGTChv7nNGgVi7uf4lYpuIj|MhQO!wZnK+yyM!;K!T diff --git a/samples/DotNetElements.CrudExample/TestDb.db-wal b/samples/DotNetElements.CrudExample/TestDb.db-wal index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..aafff1194d1d8041b311c77044d96781fca3db26 100644 GIT binary patch literal 12392 zcmeI&J!=#}7zgk@I79++#x!E%fu%g>JoEC*%ysj!+gL<2_YDjI4Wux=TG_UHKWtvH(8>e|GB00bZa0SG_<0uX=z1Rwwb z2yBqR^7-ic;=y9EyV%tx_}m*!S_VT_DNRv|BK91GUGRMld;2err}^;cVEX8&t(a?& zY@#hBB_^_|3=|}2swQ$sskcLj!(a#RVj&e-$O<#XEJ8+!vnDytI%%aXDJE7^&2y#Z zEHkSOo2c)%C#BZd#Llgoc_k*AxZ0#0>>s(n==0fL8GpK5yjcuUx>lHiMZ&8?~{kT;LZqW5fag literal 0 HcmV?d00001 diff --git a/src/DotNetElements.Core/Core/EntityBase.cs b/src/DotNetElements.Core/Core/EntityBase.cs index 4be392d..6be31c4 100644 --- a/src/DotNetElements.Core/Core/EntityBase.cs +++ b/src/DotNetElements.Core/Core/EntityBase.cs @@ -1,5 +1,4 @@ using System.ComponentModel; -using System.Diagnostics.Eventing.Reader; namespace DotNetElements.Core; @@ -59,14 +58,6 @@ public interface IDeletionAuditedEntity : IHasDeletionTime void Delete(Guid deleterId, DateTimeOffset deletionTime); } -/// -/// To make use of Ef Cores concurrency check, add a to the property. -/// -public interface IHasVersion -{ - public Guid Version { get; set; } -} - public interface IUpdatable { void Update(TFrom from, IAttachRelatedEntity attachRelatedEntity); diff --git a/src/DotNetElements.Core/Core/Extensions/ServiceCollectionExtensions.cs b/src/DotNetElements.Core/Core/Extensions/ServiceCollectionExtensions.cs index 3080025..4444285 100644 --- a/src/DotNetElements.Core/Core/Extensions/ServiceCollectionExtensions.cs +++ b/src/DotNetElements.Core/Core/Extensions/ServiceCollectionExtensions.cs @@ -1,4 +1,5 @@ -using Microsoft.Extensions.DependencyInjection; +using System.Reflection; +using Microsoft.Extensions.DependencyInjection; namespace DotNetElements.Core.Extensions; @@ -6,10 +7,10 @@ public static class ServiceCollectionExtensions { public static IReadOnlyList? RegisteredModules { get; private set; } - public static IServiceCollection RegisterModules(this IServiceCollection services) + public static IServiceCollection RegisterModules(this IServiceCollection services, Assembly moduleAssembly) { - IEnumerable modules = DiscoverModules(); - List registeredModules = new List(); + IEnumerable modules = DiscoverModules(moduleAssembly); + List registeredModules = []; foreach (IModule module in modules) { @@ -43,10 +44,9 @@ public static IServiceCollection AddDatabaseMigrationService(this IS } // todo replace with source generated version - private static IEnumerable DiscoverModules() + private static IEnumerable DiscoverModules(Assembly moduleAssembly) { - return typeof(IModule).Assembly - .GetTypes() + return moduleAssembly.GetTypes() .Where(p => p.IsAssignableTo(typeof(IModule)) && p.IsClass && !p.IsAbstract) .Select(Activator.CreateInstance) .Cast(); diff --git a/src/DotNetElements.Core/Core/IHasVersion.cs b/src/DotNetElements.Core/Core/IHasVersion.cs new file mode 100644 index 0000000..c7ab3a3 --- /dev/null +++ b/src/DotNetElements.Core/Core/IHasVersion.cs @@ -0,0 +1,20 @@ +namespace DotNetElements.Core; + +public interface IHasVersionReadOnly +{ + Guid Version { get; } +} + +// todo implement code analyzer to detect missing attribute +// - https://stackoverflow.com/questions/74377235/how-can-i-detect-missing-attributes-on-a-method-with-roslyn-code-analyser +// - https://medium.com/@niteshsinghal85/custom-code-analyzer-to-detect-usage-of-allowanonymous-attribute-in-c-a225a81ab2b4 + +/// +/// To make use of Ef Cores concurrency check, add a to the property. +/// +public interface IHasVersion : IHasVersionReadOnly +{ + Guid IHasVersionReadOnly.Version => Version; + + new Guid Version { get; set; } +} diff --git a/src/DotNetElements.Core/Core/ModelBase.cs b/src/DotNetElements.Core/Core/ModelBase.cs index 6670538..6f32a3d 100644 --- a/src/DotNetElements.Core/Core/ModelBase.cs +++ b/src/DotNetElements.Core/Core/ModelBase.cs @@ -17,7 +17,7 @@ protected Model(TKey id) } } -public abstract class VersionedModel : Model +public abstract class VersionedModel : Model, IHasVersionReadOnly where TKey : notnull { public Guid Version { get; protected set; } diff --git a/src/DotNetElements.Core/Core/Repository.cs b/src/DotNetElements.Core/Core/Repository.cs index 6568ee7..1167dd4 100644 --- a/src/DotNetElements.Core/Core/Repository.cs +++ b/src/DotNetElements.Core/Core/Repository.cs @@ -110,6 +110,13 @@ public virtual async Task> UpdateAsync> UpdateAsync Date: Thu, 11 Jan 2024 16:54:24 +0100 Subject: [PATCH 2/2] Finished index page. --- .../src/components/HomepageFeatures/index.tsx | 17 +- website/src/pages/index.tsx | 7 +- website/static/img/dotnet-bot_beach.svg | 105 +++++++++++ website/static/img/dotnet-bot_focused.svg | 100 +++++++++++ website/static/img/dotnet-logo.svg | 7 + .../static/img/undraw_docusaurus_react.svg | 170 ------------------ website/static/img/undraw_docusaurus_tree.svg | 40 ----- 7 files changed, 222 insertions(+), 224 deletions(-) create mode 100644 website/static/img/dotnet-bot_beach.svg create mode 100644 website/static/img/dotnet-bot_focused.svg create mode 100644 website/static/img/dotnet-logo.svg delete mode 100644 website/static/img/undraw_docusaurus_react.svg delete mode 100644 website/static/img/undraw_docusaurus_tree.svg diff --git a/website/src/components/HomepageFeatures/index.tsx b/website/src/components/HomepageFeatures/index.tsx index dadc176..9955ee1 100644 --- a/website/src/components/HomepageFeatures/index.tsx +++ b/website/src/components/HomepageFeatures/index.tsx @@ -11,31 +11,28 @@ type FeatureItem = { const FeatureList: FeatureItem[] = [ { title: 'Easy to Use', - Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default, + Svg: require('@site/static/img/dotnet-bot_beach.svg').default, description: ( <> - Docusaurus was designed from the ground up to be easily installed and - used to get your website up and running quickly. + Designed for seamless setup and integration, ensuring your development process is smooth and efficient. ), }, { title: 'Focus on What Matters', - Svg: require('@site/static/img/undraw_docusaurus_tree.svg').default, + Svg: require('@site/static/img/dotnet-bot_focused.svg').default, description: ( <> - Docusaurus lets you focus on your docs, and we'll do the chores. Go - ahead and move your docs into the docs directory. + Optimize your productivity with DotNet Elements, letting you concentrate on innovative solutions while the framework handles the routine tasks. ), }, { - title: 'Powered by React', - Svg: require('@site/static/img/undraw_docusaurus_react.svg').default, + title: 'Powered by .NET', + Svg: require('@site/static/img/dotnet-logo.svg').default, description: ( <> - Extend or customize your website layout by reusing React. Docusaurus can - be extended while reusing the same header and footer. + Leverage the robust capabilities of .NET and make use of the large community driven ecosystem. ), }, diff --git a/website/src/pages/index.tsx b/website/src/pages/index.tsx index 8b53777..94cb12b 100644 --- a/website/src/pages/index.tsx +++ b/website/src/pages/index.tsx @@ -11,10 +11,10 @@ function HomepageHeader() {
-
+

Opinionated framework to build .NET applications fast and easy
while - focusing more on the final product and less on writing low level + focusing more on the final product and less on writing low-level code.

@@ -42,8 +42,7 @@ function HomepageHeader() { >

Framework is work in progress and not considered production ready - (while still used in some personal projects). Feel free to try it and - leave suggestions. + (while still used in some personal projects). Feel free to try it out and share your thoughts.

diff --git a/website/static/img/dotnet-bot_beach.svg b/website/static/img/dotnet-bot_beach.svg new file mode 100644 index 0000000..08f993b --- /dev/null +++ b/website/static/img/dotnet-bot_beach.svg @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/website/static/img/dotnet-bot_focused.svg b/website/static/img/dotnet-bot_focused.svg new file mode 100644 index 0000000..20a7c16 --- /dev/null +++ b/website/static/img/dotnet-bot_focused.svg @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/website/static/img/dotnet-logo.svg b/website/static/img/dotnet-logo.svg new file mode 100644 index 0000000..fcc7a91 --- /dev/null +++ b/website/static/img/dotnet-logo.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/website/static/img/undraw_docusaurus_react.svg b/website/static/img/undraw_docusaurus_react.svg deleted file mode 100644 index 94b5cf0..0000000 --- a/website/static/img/undraw_docusaurus_react.svg +++ /dev/null @@ -1,170 +0,0 @@ - - Powered by React - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/website/static/img/undraw_docusaurus_tree.svg b/website/static/img/undraw_docusaurus_tree.svg deleted file mode 100644 index d9161d3..0000000 --- a/website/static/img/undraw_docusaurus_tree.svg +++ /dev/null @@ -1,40 +0,0 @@ - - Focus on What Matters - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -