Add persistence
This commit is contained in:
parent
2721f57b9c
commit
c9da4cc805
@ -17,5 +17,13 @@
|
||||
<ItemGroup Label="Microsoft">
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="$(MicrosoftVersion)" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.OpenApi" Version="$(MicrosoftVersion)" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="$(MicrosoftVersion)" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="$(MicrosoftVersion)" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Label="EntityFramework">
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="8.0.3" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.3" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.3" />
|
||||
<PackageVersion Include="Pomelo.EntityFrameworkCore.MySql" Version="8.0.2" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@ -16,6 +16,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nocr.Users.Host", "src\Nocr
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nocr.Users.Api.Contracts", "src\Nocr.Users.Api.Contracts\Nocr.Users.Api.Contracts.csproj", "{4DDFB05F-DFC7-4BD6-B593-AD52CF1B002E}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Contracts", "Contracts", "{CA3AA87B-9217-4A2D-9EBA-BFC415B63818}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nocr.Users.Persistence", "src\Nocr.Users.Persistence\Nocr.Users.Persistence.csproj", "{51C01BA8-E3E1-45F4-9DDF-6E08DAF5BB46}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@ -38,5 +42,12 @@ Global
|
||||
{4DDFB05F-DFC7-4BD6-B593-AD52CF1B002E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4DDFB05F-DFC7-4BD6-B593-AD52CF1B002E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4DDFB05F-DFC7-4BD6-B593-AD52CF1B002E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{51C01BA8-E3E1-45F4-9DDF-6E08DAF5BB46}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{51C01BA8-E3E1-45F4-9DDF-6E08DAF5BB46}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{51C01BA8-E3E1-45F4-9DDF-6E08DAF5BB46}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{51C01BA8-E3E1-45F4-9DDF-6E08DAF5BB46}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{4DDFB05F-DFC7-4BD6-B593-AD52CF1B002E} = {CA3AA87B-9217-4A2D-9EBA-BFC415B63818}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Nocr.Users.AppServices.Users.Repositories;
|
||||
using Nocr.Users.AppServices.Users.Services;
|
||||
|
||||
namespace Nocr.Users.AppServices;
|
||||
@ -11,8 +10,6 @@ public static class ServiceCollectionExtensions
|
||||
if (services == null)
|
||||
throw new ArgumentNullException(nameof(services));
|
||||
|
||||
// Add registrations here
|
||||
services.AddSingleton<IUsersRepository, InMemoryUsersRepository>();
|
||||
services.AddScoped<IUsersService, UsersService>();
|
||||
|
||||
return services;
|
||||
|
||||
@ -1,40 +0,0 @@
|
||||
using Nocr.Users.Api.Contracts.Users;
|
||||
|
||||
namespace Nocr.Users.AppServices.Users.Repositories;
|
||||
|
||||
public sealed class InMemoryUsersRepository : IUsersRepository
|
||||
{
|
||||
private long _id = 0;
|
||||
|
||||
private long _userIdentityId = 0;
|
||||
|
||||
private readonly List<User> _users = new();
|
||||
|
||||
public Task<long> Create(User user, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var id = Interlocked.Increment(ref _id);
|
||||
user.Id = id;
|
||||
_users.Add(user);
|
||||
|
||||
foreach (var identity in user.Identities)
|
||||
{
|
||||
identity.Id = Interlocked.Increment(ref _userIdentityId);
|
||||
}
|
||||
|
||||
return Task.FromResult(id);
|
||||
}
|
||||
|
||||
public Task<User?> GetUserById(long id, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Task.FromResult(_users.FirstOrDefault(x => x.Id == id));
|
||||
}
|
||||
|
||||
public Task<User?> GetByIdentity(UserIdentityType identityType, string identity,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var user = _users.SingleOrDefault(x => x.Identities.Any(i =>
|
||||
i.Type == identityType && i.Identity.Equals(identity, StringComparison.OrdinalIgnoreCase)));
|
||||
|
||||
return Task.FromResult(user);
|
||||
}
|
||||
}
|
||||
@ -10,6 +10,13 @@ public sealed class User
|
||||
|
||||
public IReadOnlyCollection<UserIdentity> Identities => _identities;
|
||||
|
||||
/// <summary>
|
||||
/// Used by ef.
|
||||
/// </summary>
|
||||
private User()
|
||||
{
|
||||
}
|
||||
|
||||
private User(string username, params UserIdentity[] identities)
|
||||
{
|
||||
Username = username;
|
||||
|
||||
@ -8,6 +8,8 @@ public sealed class UserIdentity
|
||||
|
||||
public string Identity { get; private set; }
|
||||
|
||||
public long UserId { get; private set; }
|
||||
|
||||
public UserIdentityType Type { get; private set; }
|
||||
|
||||
private UserIdentity(string identity, UserIdentityType type)
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
using Nocr.Users.AppServices;
|
||||
using Nocr.Users.Core.Dates;
|
||||
using Nocr.Users.Persistence;
|
||||
|
||||
namespace Nocr.Users.Host.Infrastructure;
|
||||
|
||||
@ -22,6 +23,7 @@ public class Startup
|
||||
services.AddSwaggerGen();
|
||||
|
||||
services.AddAppServices();
|
||||
services.AddEfPersistence(Configuration.GetConnectionString(nameof(UsersContext))!);
|
||||
}
|
||||
|
||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" />
|
||||
<PackageReference Include="Serilog.AspNetCore" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" />
|
||||
@ -14,6 +15,7 @@
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Nocr.Users.Api.Contracts\Nocr.Users.Api.Contracts.csproj" />
|
||||
<ProjectReference Include="..\Nocr.Users.AppServices\Nocr.Users.AppServices.csproj" />
|
||||
<ProjectReference Include="..\Nocr.Users.Persistence\Nocr.Users.Persistence.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@ -8,5 +8,8 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
"UsersContext": "server=localhost;port=3307;database=nocr_users;uid=root;pwd=toor"
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,5 +18,8 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
"UsersContext": "server=nocr-users-db;port=3306;database=nocr_users;uid=root;pwd=toor"
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,21 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Design;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace Nocr.Users.Persistence;
|
||||
|
||||
public class DesignTimeTextMatcherContextFactory : IDesignTimeDbContextFactory<UsersContext>
|
||||
{
|
||||
public UsersContext CreateDbContext(string[] args)
|
||||
{
|
||||
var optionsBuilder = new DbContextOptionsBuilder<UsersContext>();
|
||||
var configuration = new ConfigurationBuilder()
|
||||
.AddJsonFile("appsettings.json")
|
||||
.Build();
|
||||
|
||||
var connectionString = configuration.GetConnectionString("MariaLocal");
|
||||
optionsBuilder.UseMySql(connectionString, new MariaDbServerVersion(MariaDbServerVersion.LatestSupportedServerVersion));
|
||||
|
||||
return new UsersContext(optionsBuilder.Options);
|
||||
}
|
||||
}
|
||||
93
src/Nocr.Users.Persistence/Migrations/20240330070727_InitialMigration.Designer.cs
generated
Normal file
93
src/Nocr.Users.Persistence/Migrations/20240330070727_InitialMigration.Designer.cs
generated
Normal file
@ -0,0 +1,93 @@
|
||||
// <auto-generated />
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Nocr.Users.Persistence;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Nocr.Users.Persistence.Migrations
|
||||
{
|
||||
[DbContext(typeof(UsersContext))]
|
||||
[Migration("20240330070727_InitialMigration")]
|
||||
partial class InitialMigration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "8.0.3")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 64);
|
||||
|
||||
MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("Nocr.Users.AppServices.Users.User", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint");
|
||||
|
||||
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<long>("Id"));
|
||||
|
||||
b.Property<string>("Username")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(255)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("Username")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("UX_users_username");
|
||||
|
||||
b.ToTable("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Nocr.Users.AppServices.Users.UserIdentity", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint");
|
||||
|
||||
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<long>("Id"));
|
||||
|
||||
b.Property<string>("Identity")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(255)");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<long>("UserId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.HasIndex("Identity", "Type")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("UX_users_identity_identity_type");
|
||||
|
||||
b.ToTable("UserIdentity");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Nocr.Users.AppServices.Users.UserIdentity", b =>
|
||||
{
|
||||
b.HasOne("Nocr.Users.AppServices.Users.User", null)
|
||||
.WithMany("Identities")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.NoAction)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Nocr.Users.AppServices.Users.User", b =>
|
||||
{
|
||||
b.Navigation("Identities");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,82 @@
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Nocr.Users.Persistence.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class InitialMigration : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterDatabase()
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Users",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<long>(type: "bigint", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
Username = table.Column<string>(type: "varchar(255)", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Users", x => x.Id);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "UserIdentity",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<long>(type: "bigint", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
Identity = table.Column<string>(type: "varchar(255)", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
UserId = table.Column<long>(type: "bigint", nullable: false),
|
||||
Type = table.Column<int>(type: "int", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_UserIdentity", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_UserIdentity_Users_UserId",
|
||||
column: x => x.UserId,
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id");
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_UserIdentity_UserId",
|
||||
table: "UserIdentity",
|
||||
column: "UserId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "UX_users_identity_identity_type",
|
||||
table: "UserIdentity",
|
||||
columns: new[] { "Identity", "Type" },
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "UX_users_username",
|
||||
table: "Users",
|
||||
column: "Username",
|
||||
unique: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "UserIdentity");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Users");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,90 @@
|
||||
// <auto-generated />
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Nocr.Users.Persistence;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Nocr.Users.Persistence.Migrations
|
||||
{
|
||||
[DbContext(typeof(UsersContext))]
|
||||
partial class UsersContextModelSnapshot : ModelSnapshot
|
||||
{
|
||||
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "8.0.3")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 64);
|
||||
|
||||
MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("Nocr.Users.AppServices.Users.User", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint");
|
||||
|
||||
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<long>("Id"));
|
||||
|
||||
b.Property<string>("Username")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(255)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("Username")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("UX_users_username");
|
||||
|
||||
b.ToTable("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Nocr.Users.AppServices.Users.UserIdentity", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint");
|
||||
|
||||
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<long>("Id"));
|
||||
|
||||
b.Property<string>("Identity")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(255)");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<long>("UserId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.HasIndex("Identity", "Type")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("UX_users_identity_identity_type");
|
||||
|
||||
b.ToTable("UserIdentity");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Nocr.Users.AppServices.Users.UserIdentity", b =>
|
||||
{
|
||||
b.HasOne("Nocr.Users.AppServices.Users.User", null)
|
||||
.WithMany("Identities")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.NoAction)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Nocr.Users.AppServices.Users.User", b =>
|
||||
{
|
||||
b.Navigation("Identities");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
26
src/Nocr.Users.Persistence/Nocr.Users.Persistence.csproj
Normal file
26
src/Nocr.Users.Persistence/Nocr.Users.Persistence.csproj
Normal file
@ -0,0 +1,26 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" />
|
||||
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Nocr.Users.AppServices\Nocr.Users.AppServices.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Remove="appsettings.json" />
|
||||
<Content Include="appsettings.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
32
src/Nocr.Users.Persistence/ServiceCollectionExtensions.cs
Normal file
32
src/Nocr.Users.Persistence/ServiceCollectionExtensions.cs
Normal file
@ -0,0 +1,32 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Nocr.Users.AppServices.Users.Repositories;
|
||||
using Nocr.Users.Persistence.Users;
|
||||
|
||||
namespace Nocr.Users.Persistence;
|
||||
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
public static IServiceCollection AddEfPersistence(this IServiceCollection services, string connectionString)
|
||||
{
|
||||
if (services == null)
|
||||
throw new ArgumentNullException(nameof(services));
|
||||
|
||||
if (string.IsNullOrWhiteSpace(connectionString))
|
||||
throw new ArgumentNullException(nameof(connectionString));
|
||||
|
||||
services.AddScoped<IUsersRepository, UsersRepository>();
|
||||
|
||||
services.AddDbContext<UsersContext>(
|
||||
(ctx, context) =>
|
||||
{
|
||||
context.UseMySql(connectionString, new MariaDbServerVersion(MariaDbServerVersion.LatestSupportedServerVersion),
|
||||
builder => builder.MigrationsAssembly(typeof(UsersContext).Assembly.FullName))
|
||||
.UseLoggerFactory(ctx.GetRequiredService<ILoggerFactory>());
|
||||
}
|
||||
);
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
||||
39
src/Nocr.Users.Persistence/Users/UserConfiguration.cs
Normal file
39
src/Nocr.Users.Persistence/Users/UserConfiguration.cs
Normal file
@ -0,0 +1,39 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using Nocr.Users.AppServices.Users;
|
||||
|
||||
namespace Nocr.Users.Persistence.Users;
|
||||
|
||||
public class UserConfiguration : IEntityTypeConfiguration<User>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<User> builder)
|
||||
{
|
||||
builder.HasKey(x => x.Id);
|
||||
builder.Property(x => x.Username)
|
||||
.IsRequired();
|
||||
|
||||
builder.HasIndex(x => x.Username)
|
||||
.IsUnique()
|
||||
.HasDatabaseName("UX_users_username");
|
||||
|
||||
builder
|
||||
.HasMany(u => u.Identities)
|
||||
.WithOne()
|
||||
.HasForeignKey(x => x.UserId)
|
||||
.OnDelete(DeleteBehavior.NoAction);
|
||||
}
|
||||
}
|
||||
|
||||
public class UserIdentityConfiguration : IEntityTypeConfiguration<UserIdentity>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<UserIdentity> builder)
|
||||
{
|
||||
builder.HasKey(x => x.Id);
|
||||
builder.Property(x => x.Identity)
|
||||
.IsRequired();
|
||||
|
||||
builder.HasIndex(x => new { x.Identity, x.Type })
|
||||
.IsUnique()
|
||||
.HasDatabaseName("UX_users_identity_identity_type");
|
||||
}
|
||||
}
|
||||
38
src/Nocr.Users.Persistence/Users/UsersRepository.cs
Normal file
38
src/Nocr.Users.Persistence/Users/UsersRepository.cs
Normal file
@ -0,0 +1,38 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Nocr.Users.Api.Contracts.Users;
|
||||
using Nocr.Users.AppServices.Users;
|
||||
using Nocr.Users.AppServices.Users.Repositories;
|
||||
|
||||
namespace Nocr.Users.Persistence.Users;
|
||||
|
||||
public class UsersRepository : IUsersRepository
|
||||
{
|
||||
private readonly UsersContext _db;
|
||||
|
||||
public UsersRepository(UsersContext db)
|
||||
{
|
||||
_db = db ?? throw new ArgumentNullException(nameof(db));
|
||||
}
|
||||
|
||||
public async Task<long> Create(User user, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var userId = await _db.Users.AddAsync(user, cancellationToken);
|
||||
await _db.SaveChangesAsync(cancellationToken);
|
||||
|
||||
return userId.Entity.Id;
|
||||
}
|
||||
|
||||
public Task<User?> GetUserById(long id, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return _db.Users.Include(x => x.Identities)
|
||||
.FirstOrDefaultAsync(x => x.Id == id, cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
public Task<User?> GetByIdentity(UserIdentityType identityType, string identity,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
return _db.Users.Include(x => x.Identities)
|
||||
.FirstOrDefaultAsync(x => x.Identities.Any(i => i.Type == identityType && i.Identity == identity),
|
||||
cancellationToken: cancellationToken);
|
||||
}
|
||||
}
|
||||
23
src/Nocr.Users.Persistence/UsersContext.cs
Normal file
23
src/Nocr.Users.Persistence/UsersContext.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Nocr.Users.AppServices.Users;
|
||||
using Nocr.Users.Persistence.Users;
|
||||
|
||||
namespace Nocr.Users.Persistence;
|
||||
|
||||
public class UsersContext : DbContext
|
||||
{
|
||||
public DbSet<User> Users { get; set; }
|
||||
|
||||
public UsersContext(DbContextOptions options)
|
||||
: base(options)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.ApplyConfiguration(new UserConfiguration());
|
||||
modelBuilder.ApplyConfiguration(new UserIdentityConfiguration());
|
||||
|
||||
base.OnModelCreating(modelBuilder);
|
||||
}
|
||||
}
|
||||
5
src/Nocr.Users.Persistence/appsettings.json
Normal file
5
src/Nocr.Users.Persistence/appsettings.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"ConnectionStrings": {
|
||||
"MariaLocal": "server=localhost;port=3307;database=nocr_users;uid=root;pwd=toor"
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user