Skip to content

Commit

Permalink
Update to .NET 7 (#448)
Browse files Browse the repository at this point in the history
* Update to .NET 7

* Change github action config to use .NET 7

* Add Contributor Entity

* Configure FastEndpoints for use and for swagger

* Add a CreateContributor FastEndpoint

* Implement DeleteContributor FastEndpoint

* Implement Contributor List FastEndpoint

* Implement Contributor Update FastEndpoint

* Implement GetById Contributor FastEndpoint

* Update all packages to stable version of .NET 7

* Update codeql-analysis.yml

* Update global.json

* Update DeleteContributorSevice_DeleteContributor.cs

Update based on CodeQL suggestions

* Update ContributorConstructor.cs

Update based on CodeQL suggestions

Co-authored-by: Steve Smith <steve@kentsmiths.com>
Co-authored-by: Kyle McMaster <KyleMcMaster@users.noreply.github.com>
  • Loading branch information
3 people committed Nov 17, 2022
1 parent 3d245b5 commit 08d7872
Show file tree
Hide file tree
Showing 45 changed files with 637 additions and 39 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ jobs:

- name: Initialize CodeQL
id: init_codeql
uses: github/codeql-action/init@v1
uses: github/codeql-action/init@v2
with:
queries: security-and-quality

- name: Autobuild
uses: github/codeql-action/autobuild@v1
uses: github/codeql-action/autobuild@v2

- name: Perform CodeQL Analysis
id: analyze_codeql
uses: github/codeql-action/analyze@v1
uses: github/codeql-action/analyze@v2

# Built with ❤ by [Pipeline Foundation](https://pipeline.foundation)
# Built with ❤ by [Pipeline Foundation](https://pipeline.foundation)
2 changes: 1 addition & 1 deletion .github/workflows/dotnetcore.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
- name: Setup .NET Core
uses: actions/setup-dotnet@v1
with:
dotnet-version: '6.0.x'
dotnet-version: '7.0.x'
- name: Build with dotnet
run: dotnet build --configuration Release
- name: Test with dotnet
Expand Down
4 changes: 2 additions & 2 deletions CleanArchitecture.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
<metadata>
<id>Ardalis.CleanArchitecture.Template</id>
<title>ASP.NET Core Clean Architecture Solution</title>
<version>6.2.8</version>
<version>7.0.0</version>
<authors>Steve Smith, Erik Dahl</authors>
<description>
The Clean Architecture Solution Template popularized by Steve @ardalis Smith. Provides a great starting point for modern and/or DDD solutions built with .NET 6 and C# 10.
The Clean Architecture Solution Template popularized by Steve @ardalis Smith. Provides a great starting point for modern and/or DDD solutions built with .NET 7 and C# 11.
Features zero tight coupling to database or data access technology.
</description>
<language>en-US</language>
Expand Down
30 changes: 17 additions & 13 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,25 @@
<PackageVersion Include="Ardalis.Specification.EntityFrameworkCore" Version="6.1.0" />
<PackageVersion Include="Autofac" Version="6.4.0" />
<PackageVersion Include="Autofac.Extensions.DependencyInjection" Version="8.0.0" />
<PackageVersion Include="coverlet.collector" Version="3.1.2" />
<PackageVersion Include="coverlet.collector" Version="3.2.0" />
<PackageVersion Include="FastEndpoints" Version="5.3.2" />
<PackageVersion Include="FastEndpoints.ApiExplorer" Version="2.0.1" />
<PackageVersion Include="FastEndpoints.Swagger" Version="5.2.1" />
<PackageVersion Include="FastEndpoints.Swagger.Swashbuckle" Version="2.0.1" />
<PackageVersion Include="MediatR" Version="11.0.0" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.10" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="6.0.10" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.InMemory" Version="6.0.10" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.10" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.10" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.10" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
<PackageVersion Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="6.0.10" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="7.0.0" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="7.0.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.5.0-preview-20221003-04" />
<PackageVersion Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="7.0.0" />
<PackageVersion Include="Moq" Version="4.18.2" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.1" />
<PackageVersion Include="ReportGenerator" Version="5.1.10" />
<PackageVersion Include="Serilog.AspNetCore" Version="6.0.1" />
<PackageVersion Include="Serilog.Sinks.ApplicationInsights" Version="4.0.0" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.2-beta2" />
<PackageVersion Include="ReportGenerator" Version="5.1.11" />
<PackageVersion Include="Serilog.AspNetCore" Version="6.1.0-dev-00285" />
<PackageVersion Include="Serilog.Sinks.ApplicationInsights" Version="4.0.1-dev-00040" />
<PackageVersion Include="SQLite" Version="3.13.0" />
<PackageVersion Include="Swashbuckle.AspNetCore" Version="6.4.0" />
<PackageVersion Include="Swashbuckle.AspNetCore.Annotations" Version="6.4.0" />
Expand Down
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"sdk": {
"version": "6.0.300",
"version": "7.0.100",
"rollForward": "latestMajor"
}
}
2 changes: 1 addition & 1 deletion src/Clean.Architecture.Core/Clean.Architecture.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<Sdk Name="Microsoft.Build.CentralPackageVersions" Version="2.1.3" />

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
Expand Down
20 changes: 20 additions & 0 deletions src/Clean.Architecture.Core/ContributorAggregate/Contributor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Ardalis.GuardClauses;
using Clean.Architecture.SharedKernel;
using Clean.Architecture.SharedKernel.Interfaces;

namespace Clean.Architecture.Core.ContributorAggregate;

public class Contributor : EntityBase, IAggregateRoot
{
public string Name { get; private set; }

public Contributor(string name)
{
Name = Guard.Against.NullOrEmpty(name, nameof(name));
}

public void UpdateName(string newName)
{
Name = Guard.Against.NullOrEmpty(newName, nameof(newName));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Clean.Architecture.SharedKernel;

namespace Clean.Architecture.Core.ContributorAggregate.Events;

public class ContributorDeletedEvent : DomainEventBase
{
public int ContributorId { get; set; }

public ContributorDeletedEvent(int contributorId)
{
ContributorId = contributorId;
}
}
3 changes: 3 additions & 0 deletions src/Clean.Architecture.Core/DefaultCoreModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,8 @@ protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<ToDoItemSearchService>()
.As<IToDoItemSearchService>().InstancePerLifetimeScope();

builder.RegisterType<DeleteContributorService>()
.As<IDeleteContributorService>().InstancePerLifetimeScope();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using Ardalis.Result;

namespace Clean.Architecture.Core.Interfaces;

public interface IDeleteContributorService
{
public Task<Result> DeleteContributor(int contributorId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Clean.Architecture.Core.ContributorAggregate;
using Clean.Architecture.SharedKernel;

namespace Clean.Architecture.Core.ProjectAggregate.Events;

public class ContributorAddedToItemEvent : DomainEventBase
{
public int ContributorId { get; set; }
public ToDoItem Item { get; set; }

public ContributorAddedToItemEvent(ToDoItem item, int contributorId)
{
Item = item;
ContributorId = contributorId;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using Clean.Architecture.Core.ContributorAggregate.Events;
using Clean.Architecture.SharedKernel.Interfaces;
using Clean.Architecture.Core.ProjectAggregate.Specifications;
using MediatR;

namespace Clean.Architecture.Core.ProjectAggregate.Handlers;

public class ContributorDeletedHandler : INotificationHandler<ContributorDeletedEvent>
{
private readonly IRepository<Project> _repository;

public ContributorDeletedHandler(IRepository<Project> repository)
{
_repository = repository;
}

public async Task Handle(ContributorDeletedEvent domainEvent, CancellationToken cancellationToken)
{
var projectSpec = new ProjectsWithItemsByContributorIdSpec(domainEvent.ContributorId);
var projects = await _repository.ListAsync(projectSpec);
foreach (var project in projects)
{
project.Items
.Where(item => item.ContributorId == domainEvent.ContributorId)
.ToList()
.ForEach(item => item.RemoveContributor());
await _repository.UpdateAsync(project);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using Ardalis.Specification;

namespace Clean.Architecture.Core.ContributorAggregate.Specifications;

public class ContributorByIdSpec : Specification<Contributor>, ISingleResultSpecification
{
public ContributorByIdSpec(int contributorId)
{
Query
.Where(contributor => contributor.Id == contributorId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Ardalis.Specification;

namespace Clean.Architecture.Core.ProjectAggregate.Specifications;

public class ProjectsWithItemsByContributorIdSpec : Specification<Project>, ISingleResultSpecification
{
public ProjectsWithItemsByContributorIdSpec(int contributorId)
{
Query
.Where(project => project.Items.Where(item => item.ContributorId == contributorId).Any())
.Include(project => project.Items);
}
}
18 changes: 17 additions & 1 deletion src/Clean.Architecture.Core/ProjectAggregate/ToDoItem.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Clean.Architecture.Core.ProjectAggregate.Events;
using Ardalis.GuardClauses;
using Clean.Architecture.Core.ProjectAggregate.Events;
using Clean.Architecture.SharedKernel;

namespace Clean.Architecture.Core.ProjectAggregate;
Expand All @@ -7,6 +8,7 @@ public class ToDoItem : EntityBase
{
public string Title { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public int? ContributorId { get; private set; }
public bool IsDone { get; private set; }

public void MarkComplete()
Expand All @@ -19,6 +21,20 @@ public void MarkComplete()
}
}

public void AddContributor(int contributorId)
{
Guard.Against.Null(contributorId, nameof(contributorId));
ContributorId = contributorId;

var contributorAddedToItem = new ContributorAddedToItemEvent(this, contributorId);
base.RegisterDomainEvent(contributorAddedToItem);
}

public void RemoveContributor()
{
ContributorId = null;
}

public override string ToString()
{
string status = IsDone ? "Done!" : "Not done.";
Expand Down
31 changes: 31 additions & 0 deletions src/Clean.Architecture.Core/Services/DeleteContributorService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using Ardalis.Result;
using Clean.Architecture.Core.ContributorAggregate;
using Clean.Architecture.Core.ContributorAggregate.Events;
using Clean.Architecture.Core.Interfaces;
using Clean.Architecture.SharedKernel.Interfaces;
using MediatR;

namespace Clean.Architecture.Core.Services;

public class DeleteContributorService : IDeleteContributorService
{
private readonly IRepository<Contributor> _repository;
private readonly IMediator _mediator;

public DeleteContributorService(IRepository<Contributor> repository, IMediator mediator)
{
_repository = repository;
_mediator = mediator;
}

public async Task<Result> DeleteContributor(int contributorId)
{
var aggregateToDelete = await _repository.GetByIdAsync(contributorId);
if (aggregateToDelete == null) return Result.NotFound();

await _repository.DeleteAsync(aggregateToDelete);
var domainEvent = new ContributorDeletedEvent(contributorId);
await _mediator.Publish(domainEvent);
return Result.Success();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<Sdk Name="Microsoft.Build.CentralPackageVersions" Version="2.1.3" />

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
Expand Down
2 changes: 2 additions & 0 deletions src/Clean.Architecture.Infrastructure/Data/AppDbContext.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Reflection;
using Clean.Architecture.Core.ContributorAggregate;
using Clean.Architecture.Core.ProjectAggregate;
using Clean.Architecture.SharedKernel;
using Clean.Architecture.SharedKernel.Interfaces;
Expand All @@ -19,6 +20,7 @@ public AppDbContext(DbContextOptions<AppDbContext> options,

public DbSet<ToDoItem> ToDoItems => Set<ToDoItem>();
public DbSet<Project> Projects => Set<Project>();
public DbSet<Contributor> Contributors => Set<Contributor>();

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using Clean.Architecture.Core.ContributorAggregate;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace Clean.Architecture.Infrastructure.Data.Config;

public class ContributorConfiguration : IEntityTypeConfiguration<Contributor>
{
public void Configure(EntityTypeBuilder<Contributor> builder)
{
builder.Property(p => p.Name)
.HasMaxLength(100)
.IsRequired();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,7 @@ public void Configure(EntityTypeBuilder<ToDoItem> builder)
{
builder.Property(t => t.Title)
.IsRequired();
builder.Property(t => t.ContributorId)
.IsRequired(false);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
Expand Down
5 changes: 4 additions & 1 deletion src/Clean.Architecture.Web/Clean.Architecture.Web.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<Sdk Name="Microsoft.Build.CentralPackageVersions" Version="2.1.3" />

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net7.0</TargetFramework>
<PreserveCompilationContext>true</PreserveCompilationContext>
<OutputType>Exe</OutputType>
<WebProjectMode>true</WebProjectMode>
Expand All @@ -15,6 +15,9 @@
<PackageReference Include="Ardalis.ListStartupServices" />
<PackageReference Include="Ardalis.Result" />
<PackageReference Include="Ardalis.Result.AspNetCore" />
<PackageReference Include="FastEndpoints" />
<PackageReference Include="FastEndpoints.ApiExplorer" />
<PackageReference Include="FastEndpoints.Swagger.Swashbuckle" />
<PackageReference Include="MediatR" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" PrivateAssets="all" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
namespace Clean.Architecture.Web.Endpoints.ContributorEndpoints;

public record ContributorRecord(int Id, string Name);
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System.ComponentModel.DataAnnotations;

namespace Clean.Architecture.Web.Endpoints.ContributorEndpoints;

public class CreateContributorRequest
{
public const string Route = "/Contributors";

[Required]
public string? Name { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace Clean.Architecture.Web.Endpoints.ContributorEndpoints;

public class CreateContributorResponse
{
public CreateContributorResponse(int id, string name)
{
Id = id;
Name = name;
}
public int Id { get; set; }
public string Name { get; set; }
}
Loading

0 comments on commit 08d7872

Please sign in to comment.