Skip to content

Commit a32c7e0

Browse files
committed
Stream 21 Aug 2021
1 parent 74aabb8 commit a32c7e0

26 files changed

+424
-13
lines changed
+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
using System.Linq;
2+
3+
namespace IOKode.Cloe.Application
4+
{
5+
public interface IQueryService
6+
{
7+
public IQueryable<TEntity> Query<TEntity>();
8+
}
9+
}
+2-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
using System.Threading;
22
using System.Threading.Tasks;
3+
using IOKode.Cloe.Application.Repositories;
34

45
namespace IOKode.Cloe.Application
56
{
67
public interface IUnitOfWork
78
{
8-
public TRepository GetRepository<TRepository>();
9+
public TRepository GetRepository<TRepository>() where TRepository : IRepository;
910
public Task CommitAsync(CancellationToken cancellationToken);
1011
}
1112
}

IOKode.Cloe.Application/Posts/Models/CreatePostModel.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using IOKode.Cloe.Domain;
44
using IOKode.Cloe.Domain.Entities;
5+
using IOKode.Cloe.Domain.ValueObjects;
56

67
namespace IOKode.Cloe.Application.Posts.Models
78
{
@@ -11,7 +12,7 @@ public record CreatePostModel
1112
public string Title { get; set; }
1213
public string SearcherTitle { get; set; }
1314
public string SearcherDescription { get; set; }
14-
public string Content { get; set; }
15+
public Markdown Content { get; set; }
1516
public DateTime? PublishDate { get; set; }
1617
public IEnumerable<string> Keywords { get; set; }
1718
}

IOKode.Cloe.Application/Posts/Models/UpdatePostModel.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using IOKode.Cloe.Domain.ValueObjects;
34

45
namespace IOKode.Cloe.Application.Posts.Models
56
{
@@ -8,7 +9,7 @@ public record UpdatePostModel
89
public string Title { get; set; }
910
public string SearcherTitle { get; set; }
1011
public string SearcherDescription { get; set; }
11-
public string Content { get; set; }
12+
public Markdown Content { get; set; }
1213
public DateTime? PublishDate { get; set; }
1314
public IEnumerable<string> Keywords { get; set; }
1415
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using System;
2+
using System.Threading;
3+
using System.Threading.Tasks;
4+
using IOKode.Cloe.Application.Repositories;
5+
using IOKode.Cloe.Domain;
6+
using IOKode.Cloe.Domain.Entities;
7+
8+
namespace IOKode.Cloe.Application.Posts.UseCases
9+
{
10+
public class ModifyPostPublishDate
11+
{
12+
private readonly IUnitOfWork _UnitOfWork;
13+
14+
public ModifyPostPublishDate(IUnitOfWork unitOfWork)
15+
{
16+
_UnitOfWork = unitOfWork;
17+
}
18+
19+
public async Task InvokeAsync(Id<Post> postId, DateTime? publishDate, CancellationToken cancellationToken)
20+
{
21+
var repository = _UnitOfWork.GetRepository<IPostRepository>();
22+
var post = await repository.GetByIdAsync(postId, cancellationToken);
23+
24+
post.PublishDate = publishDate;
25+
26+
await _UnitOfWork.CommitAsync(cancellationToken);
27+
}
28+
}
29+
}

IOKode.Cloe.Application/Repositories/IPostRepository.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55

66
namespace IOKode.Cloe.Application.Repositories
77
{
8-
public interface IPostRepository
8+
public interface IPostRepository : IRepository
99
{
1010
public Task AddAsync(Post post, CancellationToken cancellationToken);
11-
public Task<Post> GetByIdAsync(Id<Post> id, CancellationToken cancellationToken);
11+
public Task<Post?> GetByIdAsync(Id<Post> id, CancellationToken cancellationToken);
1212
public Task DeleteAsync(Id<Post> id, CancellationToken cancellationToken);
1313

1414
public async Task DeleteAsync(Post post, CancellationToken cancellationToken)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace IOKode.Cloe.Application.Repositories
2+
{
3+
public interface IRepository
4+
{
5+
6+
}
7+
}

IOKode.Cloe.Domain/Entities/Page.cs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
using IOKode.Cloe.Domain.ValueObjects;
2+
13
namespace IOKode.Cloe.Domain.Entities
24
{
35
public class Page
46
{
57
public Id<Page> Id { get; set; }
68
public string Title { get; set; }
7-
public string Content { get; set; }
9+
public Markdown Content { get; set; }
810
}
911
}

IOKode.Cloe.Domain/Entities/Post.cs

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using IOKode.Cloe.Domain.ValueObjects;
34

45
namespace IOKode.Cloe.Domain.Entities
56
{
@@ -26,8 +27,15 @@ public bool IsPublished
2627
public string Title { get; set; }
2728
public string SearcherTitle { get; set; }
2829
public string SearcherDescription { get; set; }
29-
public string Content { get; set; } // todo Change type to Markdown
30+
public Markdown Content { get; set; } // todo Change type to Markdown
3031
public IList<string> Keywords { get; set; }
3132
public Id<User> AuthorId { get; set; }
33+
34+
public void Publish(DateTime publishDate)
35+
{
36+
PublishDate = publishDate;
37+
}
38+
39+
public void Publish() => Publish(DateTime.Now);
3240
}
3341
}

IOKode.Cloe.Domain/Id.cs

+6-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ namespace IOKode.Cloe.Domain
22
{
33
public record Id<TEntity>
44
{
5-
public string Value { get; init; }
5+
public string Value { get; }
6+
7+
public Id(string value)
8+
{
9+
Value = value;
10+
}
611
}
712
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
namespace IOKode.Cloe.Domain.ValueObjects
2+
{
3+
public record Markdown
4+
{
5+
public string Value { get; }
6+
7+
public Markdown(string value)
8+
{
9+
Value = value;
10+
}
11+
}
12+
}
+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<Project Sdk="Microsoft.NET.Sdk.Web">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net5.0</TargetFramework>
5+
<Nullable>enable</Nullable>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<ProjectReference Include="..\IOKode.Cloe.Application\IOKode.Cloe.Application.csproj" />
10+
<ProjectReference Include="..\IOKode.Cloe.InMemoryPersistence\IOKode.Cloe.InMemoryPersistence.csproj" />
11+
<ProjectReference Include="..\IOKode.Cloe.Rest\IOKode.Cloe.Rest.csproj" />
12+
</ItemGroup>
13+
14+
</Project>

IOKode.Cloe.Host/Program.cs

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using Microsoft.AspNetCore.Hosting;
2+
using Microsoft.Extensions.Hosting;
3+
4+
namespace IOKode.Cloe.Host
5+
{
6+
internal static class Program
7+
{
8+
public static void Main(string[] args)
9+
{
10+
CreateHostBuilder(args).Build().Run();
11+
}
12+
13+
public static IHostBuilder CreateHostBuilder(string[] args)
14+
{
15+
return Microsoft.Extensions.Hosting.Host.CreateDefaultBuilder(args)
16+
.ConfigureWebHostDefaults(webBuilder =>
17+
{
18+
webBuilder.UseStartup<Startup>();
19+
});
20+
}
21+
}
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"iisSettings": {
3+
"windowsAuthentication": false,
4+
"anonymousAuthentication": true,
5+
"iisExpress": {
6+
"applicationUrl": "http://localhost:23426",
7+
"sslPort": 44312
8+
}
9+
},
10+
"profiles": {
11+
"IOKode.Cloe.Host": {
12+
"commandName": "Project",
13+
"dotnetRunMessages": true,
14+
"launchBrowser": true,
15+
"applicationUrl": "https://localhost:5001;http://localhost:5000",
16+
"environmentVariables": {
17+
"ASPNETCORE_ENVIRONMENT": "Development"
18+
}
19+
},
20+
"IIS Express": {
21+
"commandName": "IISExpress",
22+
"launchBrowser": true,
23+
"environmentVariables": {
24+
"ASPNETCORE_ENVIRONMENT": "Development"
25+
}
26+
}
27+
}
28+
}

IOKode.Cloe.Host/Startup.cs

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
using IOKode.Cloe.Application;
2+
using IOKode.Cloe.Application.Posts.UseCases;
3+
using IOKode.Cloe.InMemoryPersistence;
4+
using IOKode.Cloe.Rest.Controllers;
5+
using Microsoft.AspNetCore.Builder;
6+
using Microsoft.Extensions.Configuration;
7+
using Microsoft.Extensions.DependencyInjection;
8+
9+
namespace IOKode.Cloe.Host
10+
{
11+
internal class Startup
12+
{
13+
private readonly IConfiguration _Configuration;
14+
15+
public Startup(IConfiguration configuration)
16+
{
17+
_Configuration = configuration;
18+
}
19+
20+
public void ConfigureServices(IServiceCollection services)
21+
{
22+
services.AddRouting();
23+
services.AddControllers().AddApplicationPart(typeof(PostController).Assembly);
24+
25+
services.AddTransient<CreatePostUseCase>();
26+
services.AddInMemoryPersistence();
27+
}
28+
29+
public void Configure(IApplicationBuilder app)
30+
{
31+
app.UseRouting();
32+
app.UseEndpoints(endpoints =>
33+
{
34+
endpoints.MapControllers();
35+
});
36+
}
37+
}
38+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Information",
5+
"Microsoft": "Warning",
6+
"Microsoft.Hosting.Lifetime": "Information"
7+
}
8+
}
9+
}

IOKode.Cloe.Host/appsettings.json

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Information",
5+
"Microsoft": "Warning",
6+
"Microsoft.Hosting.Lifetime": "Information"
7+
}
8+
},
9+
"AllowedHosts": "*"
10+
}

IOKode.Cloe.InMemoryPersistence/IOKode.Cloe.InMemoryPersistence.csproj

+4
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,8 @@
99
<ProjectReference Include="..\IOKode.Cloe.Application\IOKode.Cloe.Application.csproj" />
1010
</ItemGroup>
1111

12+
<ItemGroup>
13+
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="5.0.0" />
14+
</ItemGroup>
15+
1216
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System;
2+
using System.Linq;
3+
using IOKode.Cloe.Application;
4+
using IOKode.Cloe.Domain.Entities;
5+
using IOKode.Cloe.InMemoryPersistence.Repositories;
6+
7+
namespace IOKode.Cloe.InMemoryPersistence
8+
{
9+
internal class InMemoryQueryService : IQueryService
10+
{
11+
public IQueryable<TEntity> Query<TEntity>()
12+
{
13+
if (typeof(TEntity).IsAssignableTo(typeof(Post)))
14+
{
15+
var repository =
16+
(InMemoryPostRepository) InMemoryUnitOfWork.GetInMemoryRepository<InMemoryPostRepository>();
17+
return (IQueryable<TEntity>) repository.PersistedItems.AsQueryable();
18+
}
19+
20+
throw new InvalidOperationException("Trying to query a not registered entity.");
21+
}
22+
}
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using IOKode.Cloe.Application;
2+
using Microsoft.Extensions.DependencyInjection;
3+
4+
namespace IOKode.Cloe.InMemoryPersistence
5+
{
6+
public static class InMemoryServiceExtensions
7+
{
8+
public static void AddInMemoryPersistence(this IServiceCollection services)
9+
{
10+
services.AddScoped<IUnitOfWork, InMemoryUnitOfWork>();
11+
services.AddTransient<IQueryService, InMemoryQueryService>();
12+
}
13+
}
14+
}

0 commit comments

Comments
 (0)