Skip to content

Commit

Permalink
Added example of basic CQRS using Endpoints, Nullable Reference Types…
Browse files Browse the repository at this point in the history
…, Records and other C# 8-9 goodies
  • Loading branch information
oskardudycz committed May 13, 2021
1 parent b2a8167 commit 699316e
Show file tree
Hide file tree
Showing 33 changed files with 1,222 additions and 0 deletions.
24 changes: 24 additions & 0 deletions EventSourcing.NetCore.sln
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tools", "Workshops\BuildYou
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solved", "Solved", "{C9011E7F-42EA-4FEE-A5BB-EFC11BBA0DB0}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Warehouse", "Warehouse", "{4AC3138B-6FD1-4620-A75A-3FCACE995162}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Warehouse", "Sample\Warehouse\Warehouse\Warehouse.csproj", "{C45ACE62-41BA-49D9-956A-39B479D7A50A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Warehouse.Api", "Sample\Warehouse\Warehouse.Api\Warehouse.Api.csproj", "{76C04CB6-32C7-47EA-884A-6343BDD39644}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Warehouse.Api.Tests", "Sample\Warehouse\Warehouse.Api.Tests\Warehouse.Api.Tests.csproj", "{69B22937-CA8B-478D-97F8-4D33558B5BC9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -419,6 +427,18 @@ Global
{5C54B28C-7746-4DD0-865E-1AC0D8E8D46B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5C54B28C-7746-4DD0-865E-1AC0D8E8D46B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5C54B28C-7746-4DD0-865E-1AC0D8E8D46B}.Release|Any CPU.Build.0 = Release|Any CPU
{C45ACE62-41BA-49D9-956A-39B479D7A50A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C45ACE62-41BA-49D9-956A-39B479D7A50A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C45ACE62-41BA-49D9-956A-39B479D7A50A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C45ACE62-41BA-49D9-956A-39B479D7A50A}.Release|Any CPU.Build.0 = Release|Any CPU
{76C04CB6-32C7-47EA-884A-6343BDD39644}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{76C04CB6-32C7-47EA-884A-6343BDD39644}.Debug|Any CPU.Build.0 = Debug|Any CPU
{76C04CB6-32C7-47EA-884A-6343BDD39644}.Release|Any CPU.ActiveCfg = Release|Any CPU
{76C04CB6-32C7-47EA-884A-6343BDD39644}.Release|Any CPU.Build.0 = Release|Any CPU
{69B22937-CA8B-478D-97F8-4D33558B5BC9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{69B22937-CA8B-478D-97F8-4D33558B5BC9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{69B22937-CA8B-478D-97F8-4D33558B5BC9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{69B22937-CA8B-478D-97F8-4D33558B5BC9}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -496,6 +516,10 @@ Global
{C9011E7F-42EA-4FEE-A5BB-EFC11BBA0DB0} = {94524EA9-A4BA-4684-99B8-BBE9EE85E791}
{7ACC398F-87BF-4B3E-AD61-DFB5F56D4B25} = {C9011E7F-42EA-4FEE-A5BB-EFC11BBA0DB0}
{03D0848C-7B19-4685-BA1F-59FFAF1DCEA6} = {C9011E7F-42EA-4FEE-A5BB-EFC11BBA0DB0}
{4AC3138B-6FD1-4620-A75A-3FCACE995162} = {A7186B6B-D56D-4AEF-B6B7-FAA827764C34}
{C45ACE62-41BA-49D9-956A-39B479D7A50A} = {4AC3138B-6FD1-4620-A75A-3FCACE995162}
{76C04CB6-32C7-47EA-884A-6343BDD39644} = {4AC3138B-6FD1-4620-A75A-3FCACE995162}
{69B22937-CA8B-478D-97F8-4D33558B5BC9} = {4AC3138B-6FD1-4620-A75A-3FCACE995162}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A5F55604-2FF3-43B7-B657-4F18E6E95D3B}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using System;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Core.Testing;
using FluentAssertions;
using Microsoft.AspNetCore.Hosting;
using Warehouse.Products.RegisteringProduct;
using Xunit;

namespace Warehouse.Api.Tests.Products.RegisteringProduct
{
public class RegisteringProduct
{
public class RegisterProductFixture: ApiFixture
{
protected override string ApiUrl => "/api/products";

protected override Func<IWebHostBuilder, IWebHostBuilder> SetupWebHostBuilder =>
WarehouseTestWebHostBuilder.Configure;
}

public class RegisterProductTests: IClassFixture<RegisterProductFixture>
{
private readonly RegisterProductFixture fixture;

public RegisterProductTests(RegisterProductFixture fixture)
{
this.fixture = fixture;
}

[Fact]
public async Task ValidRequest_ShouldReturn_OK()
{
// Given
const string sku = "test";
const string name = "test";
const string description = "test";
var request = new RegisterProductRequest(sku, name, description);

// When
var response = await fixture.Post(request);

// Then
response.EnsureSuccessStatusCode();
response.StatusCode.Should().Be(HttpStatusCode.Created);
}
}
}
}
52 changes: 52 additions & 0 deletions Sample/Warehouse/Warehouse.Api.Tests/Warehouse.Api.Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<Nullable>enable</Nullable>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="5.10.3" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" />
<PackageReference Include="Swashbuckle.AspNetCore.Swagger" Version="6.1.4" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="1.3.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>


<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\Core.Testing\Core.Testing.csproj" />
<ProjectReference Include="..\Warehouse.Api\Warehouse.Api.csproj" />
<ProjectReference Include="..\Warehouse\Warehouse.csproj" />
</ItemGroup>

<ItemGroup>
<Folder Include="Products" />
</ItemGroup>

<ItemGroup>
<Content Include="appsettings.Development.json">
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Include="appsettings.json">
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Warehouse.Storage;

namespace Warehouse.Api.Tests
{
public static class WarehouseTestWebHostBuilder
{
public static IWebHostBuilder Configure(IWebHostBuilder webHostBuilder)
{
webHostBuilder
.ConfigureServices(services =>
{
services.AddMvcCore()
.AddAuthorization()
.AddCors()
.AddDataAnnotations()
.AddFormatterMappings();

services.AddWarehouseServices();
})
.Configure(app =>
{
app.UseHttpsRedirection()
.UseRouting()
.UseAuthorization()
.UseEndpoints(endpoints => { endpoints.UseWarehouseEndpoints(); });

// Kids, do not try this at home!
app.ApplicationServices.GetRequiredService<WarehouseDBContext>().Database.Migrate();
});

return webHostBuilder;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}
13 changes: 13 additions & 0 deletions Sample/Warehouse/Warehouse.Api.Tests/appsettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ConnectionStrings": {
"WarehouseDB": "PORT = 5432; HOST = 127.0.0.1; TIMEOUT = 15; POOLING = True; MINPOOLSIZE = 1; MAXPOOLSIZE = 100; COMMANDTIMEOUT = 20; DATABASE = 'postgres'; PASSWORD = 'Password12!'; USER ID = 'postgres'"
},
"AllowedHosts": "*"
}
42 changes: 42 additions & 0 deletions Sample/Warehouse/Warehouse.Api/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;
using Warehouse;

var builder = Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder
.ConfigureServices(services =>
{
services.AddMvcCore()
.AddApiExplorer()
.AddAuthorization()
.AddCors()
.AddDataAnnotations()
.AddFormatterMappings();

services
.AddWarehouseServices()
.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo {Title = "Warehouse.Api", Version = "v1"});
});
})
.Configure(app =>
{
app.UseSwagger()
.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "CashRegisters.Api v1"))
.UseHttpsRedirection()
.UseRouting()
.UseAuthorization()
.UseEndpoints(endpoints =>
{
endpoints.UseWarehouseEndpoints();
});
});
})
.Build();
builder.Run();
31 changes: 31 additions & 0 deletions Sample/Warehouse/Warehouse.Api/Properties/launchSettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:59471",
"sslPort": 44389
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"CashRegisters.Api": {
"commandName": "Project",
"dotnetRunMessages": "true",
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
23 changes: 23 additions & 0 deletions Sample/Warehouse/Warehouse.Api/Warehouse.Api.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<Nullable>enable</Nullable>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="5.0.1" NoWarn="NU1605" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="5.0.1" NoWarn="NU1605" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.1.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.5">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Warehouse\Warehouse.csproj" />
</ItemGroup>

</Project>
9 changes: 9 additions & 0 deletions Sample/Warehouse/Warehouse.Api/appsettings.Development.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}
13 changes: 13 additions & 0 deletions Sample/Warehouse/Warehouse.Api/appsettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ConnectionStrings": {
"WarehouseDB": "PORT = 5432; HOST = 127.0.0.1; TIMEOUT = 15; POOLING = True; MINPOOLSIZE = 1; MAXPOOLSIZE = 100; COMMANDTIMEOUT = 20; DATABASE = 'postgres'; PASSWORD = 'Password12!'; USER ID = 'postgres'"
},
"AllowedHosts": "*"
}
46 changes: 46 additions & 0 deletions Sample/Warehouse/Warehouse.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Core", "Core", "{F6A27B3D-4018-4E66-A008-3E1280C8C685}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core.Testing", "..\..\Core.Testing\Core.Testing.csproj", "{DD7FF547-0FF1-4B10-9248-1E2700BA3770}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core", "..\..\Core\Core.csproj", "{35632837-CB02-455C-9570-E79E476C1D90}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Warehouse", "Warehouse\Warehouse.csproj", "{00DCEE41-018D-4CCA-99F3-00876BEB7E06}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Warehouse.Api", "Warehouse.Api\Warehouse.Api.csproj", "{46D1830E-55B1-4F36-959F-2ACF936BFC7C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Warehouse.Api.Tests", "Warehouse.Api.Tests\Warehouse.Api.Tests.csproj", "{6E5C1CF1-29FF-408E-9E01-E7109FB2ECA0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{DD7FF547-0FF1-4B10-9248-1E2700BA3770} = {F6A27B3D-4018-4E66-A008-3E1280C8C685}
{35632837-CB02-455C-9570-E79E476C1D90} = {F6A27B3D-4018-4E66-A008-3E1280C8C685}
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{DD7FF547-0FF1-4B10-9248-1E2700BA3770}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DD7FF547-0FF1-4B10-9248-1E2700BA3770}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DD7FF547-0FF1-4B10-9248-1E2700BA3770}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DD7FF547-0FF1-4B10-9248-1E2700BA3770}.Release|Any CPU.Build.0 = Release|Any CPU
{35632837-CB02-455C-9570-E79E476C1D90}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{35632837-CB02-455C-9570-E79E476C1D90}.Debug|Any CPU.Build.0 = Debug|Any CPU
{35632837-CB02-455C-9570-E79E476C1D90}.Release|Any CPU.ActiveCfg = Release|Any CPU
{35632837-CB02-455C-9570-E79E476C1D90}.Release|Any CPU.Build.0 = Release|Any CPU
{00DCEE41-018D-4CCA-99F3-00876BEB7E06}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{00DCEE41-018D-4CCA-99F3-00876BEB7E06}.Debug|Any CPU.Build.0 = Debug|Any CPU
{00DCEE41-018D-4CCA-99F3-00876BEB7E06}.Release|Any CPU.ActiveCfg = Release|Any CPU
{00DCEE41-018D-4CCA-99F3-00876BEB7E06}.Release|Any CPU.Build.0 = Release|Any CPU
{46D1830E-55B1-4F36-959F-2ACF936BFC7C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{46D1830E-55B1-4F36-959F-2ACF936BFC7C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{46D1830E-55B1-4F36-959F-2ACF936BFC7C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{46D1830E-55B1-4F36-959F-2ACF936BFC7C}.Release|Any CPU.Build.0 = Release|Any CPU
{6E5C1CF1-29FF-408E-9E01-E7109FB2ECA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6E5C1CF1-29FF-408E-9E01-E7109FB2ECA0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6E5C1CF1-29FF-408E-9E01-E7109FB2ECA0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6E5C1CF1-29FF-408E-9E01-E7109FB2ECA0}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
Loading

0 comments on commit 699316e

Please sign in to comment.