This commit is contained in:
Ivan Paulovich
2017-08-22 18:30:10 -03:00
parent 7267aa6b2f
commit 2eddbb65e2
84 changed files with 845 additions and 130 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 457 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 830 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 426 KiB

View File

@@ -1,45 +0,0 @@
public void CheckOut()
{
MailMessage myMessage = new MailMessage(
"loja@minhaloja.com",
"usuario@minhaloja.com",
"Seu pedido foi recebido.",
"Obrigado!");
SmtpClient smptClient = new SmtpClient("localhost");
smtpClient.Send(myMessage);
}
public interface ISendEmail
{
void SendMail(string to, string from, string subject, string body);
}
public class LiveSmtpMailer : ISendEmail
{
void SendMail(string to, string from, string subject, string body)
{
MailMessage myMessage = new MailMessage(from, to, subject, body);
SmtpClient smptClient = new SmtpClient("localhost");
smtpClient.Send(myMessage);
}
}
public class Cart
{
private ISendEmail _emailProvider;
public Cart(ISendEmail emailProvider)
{
_emailProvider = emailProvider;
}
public void Checkout()
{
this.emailProvider.SendMail(
"loja@minhaloja.com",
"usuario@minhaloja.com",
"Seu pedido foi recebido.",
"Obrigado!");
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 462 KiB

View File

@@ -1,8 +0,0 @@
public IRepository<T>
{
T GetById(int id);
IEnumerable<T> List();
void Create(T item);
void Update(T item);
void Delete(T item);
}

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 MiB

View File

@@ -1,7 +0,0 @@
public interface Modem
{
public void Dial(string pno);
public void Hangup();
public void Send(char c);
public char Recv();
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 580 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 788 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 616 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 492 KiB

View File

@@ -26,7 +26,7 @@ namespace Jambo.API.IoC
.As<MongoContext>().SingleInstance();
builder.RegisterType<BlogReadOnlyRepository>()
.As<IBlogReadOnlyRepository>()
.As<IPostReadOnlyRepository>()
.InstancePerLifetimeScope();
builder.RegisterType<BlogWriteOnlyRepository>()

View File

@@ -56,7 +56,7 @@ namespace Jambo.API.Controllers
}
[HttpPatch("Enable")]
public async Task<IActionResult> Enable([FromBody]UpdateBlogUrlCommand command)
public async Task<IActionResult> Enable([FromBody]EnableBlogCommand command)
{
await _mediator.Send(command);
return (IActionResult)Ok();

View File

@@ -32,7 +32,7 @@ namespace Jambo.API.Controllers
return Ok(blogs);
}
[HttpGet("{id}")]
[HttpGet("{id}", Name = "GetPost")]
public async Task<IActionResult> Get(Guid id)
{
try
@@ -52,9 +52,22 @@ namespace Jambo.API.Controllers
{
Guid id = await _mediator.Send(command);
return CreatedAtRoute("Get", new { id = id }, id);
return CreatedAtRoute("GetPost", new { id = id }, id);
}
[HttpPatch("Enable")]
public async Task<IActionResult> Enable([FromBody]EnablePostCommand command)
{
await _mediator.Send(command);
return (IActionResult)Ok();
}
[HttpPatch("Disable")]
public async Task<IActionResult> Disable([FromBody]DisablePostCommand command)
{
await _mediator.Send(command);
return (IActionResult)Ok();
}
[HttpPatch("Publish")]
public async Task<IActionResult> Publish([FromBody]PublishPostCommand command)
@@ -71,7 +84,7 @@ namespace Jambo.API.Controllers
}
[HttpPatch("UpdateContent")]
public async Task<IActionResult> UpdateContent([FromBody]UpdateContentCommand command)
public async Task<IActionResult> UpdateContent([FromBody]UpdatePostContentCommand command)
{
await _mediator.Send(command);
return (IActionResult)Ok();

View File

@@ -6,13 +6,13 @@ using MediatR;
using System;
using System.Threading.Tasks;
namespace Jambo.Application.CommandHandlers
namespace Jambo.Application.CommandHandlers.Blogs
{
public class CriarBlogCommandHandler : IAsyncRequestHandler<CreateBlogCommand, Guid>
public class CreatePostCommandHandler : IAsyncRequestHandler<CreateBlogCommand, Guid>
{
private readonly IServiceBus _serviceBus;
public CriarBlogCommandHandler(IServiceBus serviceBus)
public CreatePostCommandHandler(IServiceBus serviceBus)
{
_serviceBus = serviceBus ??
throw new ArgumentNullException(nameof(serviceBus));

View File

@@ -1,19 +1,20 @@
using Jambo.Application.Commands;
using Jambo.Application.Commands.Blogs;
using Jambo.Domain.Aggregates.Blogs;
using Jambo.Domain.Aggregates.Posts;
using Jambo.Domain.ServiceBus;
using MediatR;
using System;
using System.Threading.Tasks;
namespace Jambo.Application.CommandHandlers
namespace Jambo.Application.CommandHandlers.Blogs
{
public class ExcluirBlogCommandHandler : IAsyncRequestHandler<DisableBlogCommand>
public class DisableBlogCommandHandler : IAsyncRequestHandler<DisableBlogCommand>
{
private readonly IServiceBus _serviceBus;
private readonly IBlogReadOnlyRepository _blogReadOnlyRepository;
public ExcluirBlogCommandHandler(
public DisableBlogCommandHandler(
IServiceBus serviceBus,
IBlogReadOnlyRepository blogReadOnlyRepository)
{
@@ -26,7 +27,6 @@ namespace Jambo.Application.CommandHandlers
public async Task Handle(DisableBlogCommand message)
{
Blog blog = await _blogReadOnlyRepository.GetBlog(message.Id);
blog.Disable();
await _serviceBus.Publish(blog.GetEvents());

View File

@@ -0,0 +1,36 @@
using MediatR;
using System;
using System.Threading.Tasks;
using Jambo.Application.Commands;
using Jambo.Domain.ServiceBus;
using Jambo.Domain.Aggregates.Blogs;
using Jambo.Application.Commands.Blogs;
using Jambo.Domain.Aggregates.Posts;
using Jambo.Application.Commands.Posts;
namespace Jambo.Application.CommandHandlers.Blogs
{
public class EnableBlogCommandHandler : IAsyncRequestHandler<HidePostCommand>
{
private readonly IServiceBus _serviceBus;
private readonly IBlogReadOnlyRepository _blogReadOnlyRepository;
public EnableBlogCommandHandler(
IServiceBus serviceBus,
IBlogReadOnlyRepository blogReadOnlyRepository)
{
_serviceBus = serviceBus ??
throw new ArgumentNullException(nameof(serviceBus));
_blogReadOnlyRepository = blogReadOnlyRepository ??
throw new ArgumentNullException(nameof(blogReadOnlyRepository));
}
public async Task Handle(HidePostCommand message)
{
Blog blog = await _blogReadOnlyRepository.GetBlog(message.Id);
blog.Enable();
await _serviceBus.Publish(blog.GetEvents());
}
}
}

View File

@@ -6,14 +6,14 @@ using Jambo.Domain.ServiceBus;
using Jambo.Domain.Aggregates.Blogs;
using Jambo.Application.Commands.Blogs;
namespace Jambo.Application.CommandHandlers
namespace Jambo.Application.CommandHandlers.Blogs
{
public class AtualizarBlogCommandHandler : IAsyncRequestHandler<UpdateBlogUrlCommand>
public class UpdateBlogUrlCommandHandler : IAsyncRequestHandler<UpdateBlogUrlCommand>
{
private readonly IServiceBus _serviceBus;
private readonly IBlogReadOnlyRepository _blogReadOnlyRepository;
public AtualizarBlogCommandHandler(
public UpdateBlogUrlCommandHandler(
IServiceBus serviceBus,
IBlogReadOnlyRepository blogReadOnlyRepository)
{

View File

@@ -0,0 +1,39 @@
using Jambo.Application.Commands;
using Jambo.Application.Commands.Blogs;
using Jambo.Application.Commands.Posts;
using Jambo.Domain.Aggregates.Blogs;
using Jambo.Domain.Aggregates.Posts;
using Jambo.Domain.ServiceBus;
using MediatR;
using System;
using System.Threading.Tasks;
namespace Jambo.Application.CommandHandlers.Posts
{
public class CreatePostCommandHandler : IAsyncRequestHandler<CreatePostCommand, Guid>
{
private readonly IServiceBus _serviceBus;
private readonly IPostReadOnlyRepository _blogReadOnlyRepository;
public CreatePostCommandHandler(
IServiceBus serviceBus,
IPostReadOnlyRepository blogReadOnlyRepository)
{
_serviceBus = serviceBus ??
throw new ArgumentNullException(nameof(serviceBus));
_blogReadOnlyRepository = blogReadOnlyRepository ??
throw new ArgumentNullException(nameof(blogReadOnlyRepository));
}
public async Task<Guid> Handle(CreatePostCommand message)
{
Post post = new Post();
post.SetBlogId(message.BlogId);
post.UpdateContent(message.Title, message.Content);
await _serviceBus.Publish(post.GetEvents());
return post.Id;
}
}
}

View File

@@ -0,0 +1,36 @@
using Jambo.Application.Commands;
using Jambo.Application.Commands.Blogs;
using Jambo.Application.Commands.Posts;
using Jambo.Domain.Aggregates.Blogs;
using Jambo.Domain.Aggregates.Posts;
using Jambo.Domain.ServiceBus;
using MediatR;
using System;
using System.Threading.Tasks;
namespace Jambo.Application.CommandHandlers.Posts
{
public class DisablePostCommandHandler : IAsyncRequestHandler<DisablePostCommand>
{
private readonly IServiceBus _serviceBus;
private readonly IPostReadOnlyRepository _postReadOnlyRepository;
public DisablePostCommandHandler(
IServiceBus serviceBus,
IPostReadOnlyRepository postReadOnlyRepository)
{
_serviceBus = serviceBus ??
throw new ArgumentNullException(nameof(serviceBus));
_postReadOnlyRepository = postReadOnlyRepository ??
throw new ArgumentNullException(nameof(postReadOnlyRepository));
}
public async Task Handle(DisablePostCommand message)
{
Post post = await _postReadOnlyRepository.GetPost(message.Id);
post.Disable();
await _serviceBus.Publish(post.GetEvents());
}
}
}

View File

@@ -0,0 +1,36 @@
using Jambo.Application.Commands;
using Jambo.Application.Commands.Blogs;
using Jambo.Application.Commands.Posts;
using Jambo.Domain.Aggregates.Blogs;
using Jambo.Domain.Aggregates.Posts;
using Jambo.Domain.ServiceBus;
using MediatR;
using System;
using System.Threading.Tasks;
namespace Jambo.Application.CommandHandlers.Posts
{
public class EnablePostCommandHandler : IAsyncRequestHandler<EnablePostCommand>
{
private readonly IServiceBus _serviceBus;
private readonly IPostReadOnlyRepository _postReadOnlyRepository;
public EnablePostCommandHandler(
IServiceBus serviceBus,
IPostReadOnlyRepository postReadOnlyRepository)
{
_serviceBus = serviceBus ??
throw new ArgumentNullException(nameof(serviceBus));
_postReadOnlyRepository = postReadOnlyRepository ??
throw new ArgumentNullException(nameof(postReadOnlyRepository));
}
public async Task Handle(EnablePostCommand message)
{
Post post = await _postReadOnlyRepository.GetPost(message.Id);
post.Enable();
await _serviceBus.Publish(post.GetEvents());
}
}
}

View File

@@ -0,0 +1,36 @@
using Jambo.Application.Commands;
using Jambo.Application.Commands.Blogs;
using Jambo.Application.Commands.Posts;
using Jambo.Domain.Aggregates.Blogs;
using Jambo.Domain.Aggregates.Posts;
using Jambo.Domain.ServiceBus;
using MediatR;
using System;
using System.Threading.Tasks;
namespace Jambo.Application.CommandHandlers.Posts
{
public class HidePostCommandHandler : IAsyncRequestHandler<HidePostCommand>
{
private readonly IServiceBus _serviceBus;
private readonly IPostReadOnlyRepository _postReadOnlyRepository;
public HidePostCommandHandler(
IServiceBus serviceBus,
IPostReadOnlyRepository postReadOnlyRepository)
{
_serviceBus = serviceBus ??
throw new ArgumentNullException(nameof(serviceBus));
_postReadOnlyRepository = postReadOnlyRepository ??
throw new ArgumentNullException(nameof(postReadOnlyRepository));
}
public async Task Handle(HidePostCommand message)
{
Post post = await _postReadOnlyRepository.GetPost(message.Id);
post.Hide();
await _serviceBus.Publish(post.GetEvents());
}
}
}

View File

@@ -0,0 +1,36 @@
using Jambo.Application.Commands;
using Jambo.Application.Commands.Blogs;
using Jambo.Application.Commands.Posts;
using Jambo.Domain.Aggregates.Blogs;
using Jambo.Domain.Aggregates.Posts;
using Jambo.Domain.ServiceBus;
using MediatR;
using System;
using System.Threading.Tasks;
namespace Jambo.Application.CommandHandlers.Posts
{
public class PublishPostCommandHandler : IAsyncRequestHandler<PublishPostCommand>
{
private readonly IServiceBus _serviceBus;
private readonly IPostReadOnlyRepository _postReadOnlyRepository;
public PublishPostCommandHandler(
IServiceBus serviceBus,
IPostReadOnlyRepository postReadOnlyRepository)
{
_serviceBus = serviceBus ??
throw new ArgumentNullException(nameof(serviceBus));
_postReadOnlyRepository = postReadOnlyRepository ??
throw new ArgumentNullException(nameof(postReadOnlyRepository));
}
public async Task Handle(PublishPostCommand message)
{
Post post = await _postReadOnlyRepository.GetPost(message.Id);
post.Publish();
await _serviceBus.Publish(post.GetEvents());
}
}
}

View File

@@ -0,0 +1,36 @@
using Jambo.Application.Commands;
using Jambo.Application.Commands.Blogs;
using Jambo.Application.Commands.Posts;
using Jambo.Domain.Aggregates.Blogs;
using Jambo.Domain.Aggregates.Posts;
using Jambo.Domain.ServiceBus;
using MediatR;
using System;
using System.Threading.Tasks;
namespace Jambo.Application.CommandHandlers.Posts
{
public class UpdateContentCommandHandler : IAsyncRequestHandler<UpdatePostContentCommand>
{
private readonly IServiceBus _serviceBus;
private readonly IPostReadOnlyRepository _postReadOnlyRepository;
public UpdateContentCommandHandler(
IServiceBus serviceBus,
IPostReadOnlyRepository postReadOnlyRepository)
{
_serviceBus = serviceBus ??
throw new ArgumentNullException(nameof(serviceBus));
_postReadOnlyRepository = postReadOnlyRepository ??
throw new ArgumentNullException(nameof(postReadOnlyRepository));
}
public async Task Handle(UpdatePostContentCommand message)
{
Post post = await _postReadOnlyRepository.GetPost(message.Id);
post.UpdateContent(message.Title, message.Content);
await _serviceBus.Publish(post.GetEvents());
}
}
}

View File

@@ -13,19 +13,15 @@ namespace Jambo.Application.Commands.Blogs
[DataMember]
public string Url { get; private set; }
[DataMember]
public int Rating { get; private set; }
public UpdateBlogUrlCommand()
{
}
public UpdateBlogUrlCommand(Guid id, string url, int rating) : this()
public UpdateBlogUrlCommand(Guid id, string url) : this()
{
Id = id;
Url = url;
Rating = rating;
}
}
}

View File

@@ -1,6 +1,5 @@
using MediatR;
using System.Runtime.Serialization;
using Jambo.Application.Commands;
using System;
namespace Jambo.Application.Commands.Posts
@@ -9,16 +8,24 @@ namespace Jambo.Application.Commands.Posts
public class CreatePostCommand : IRequest<Guid>
{
[DataMember]
public string Url { get; private set; }
public Guid BlogId { get; private set; }
[DataMember]
public string Title { get; private set; }
[DataMember]
public string Content { get; private set; }
public CreatePostCommand()
{
}
public CreatePostCommand(string url) : this()
public CreatePostCommand(Guid blogId, string title, string content) : this()
{
Url = url;
BlogId = blogId;
Title = title;
Content = content;
}
}
}

View File

@@ -1,6 +1,7 @@
using MediatR;
using System.Runtime.Serialization;
using Jambo.Application.Commands;
using System;
namespace Jambo.Application.Commands.Posts
{
@@ -8,16 +9,16 @@ namespace Jambo.Application.Commands.Posts
public class DisablePostCommand : IRequest
{
[DataMember]
public string Url { get; private set; }
public Guid Id { get; private set; }
public DisablePostCommand()
{
}
public DisablePostCommand(string url) : this()
public DisablePostCommand(Guid id) : this()
{
Url = url;
Id = id;
}
}
}

View File

@@ -1,23 +1,24 @@
using MediatR;
using System.Runtime.Serialization;
using Jambo.Application.Commands;
using System;
namespace Jambo.Application.Commands.Posts
{
[DataContract]
public class UpdateContentCommand : IRequest
public class EnablePostCommand : IRequest
{
[DataMember]
public string Url { get; private set; }
public Guid Id { get; private set; }
public UpdateContentCommand()
public EnablePostCommand()
{
}
public UpdateContentCommand(string url) : this()
public EnablePostCommand(Guid id) : this()
{
Url = url;
Id = id;
}
}
}

View File

@@ -1,6 +1,7 @@
using MediatR;
using System.Runtime.Serialization;
using Jambo.Application.Commands;
using System;
namespace Jambo.Application.Commands.Posts
{
@@ -8,16 +9,16 @@ namespace Jambo.Application.Commands.Posts
public class HidePostCommand : IRequest
{
[DataMember]
public string Url { get; private set; }
public Guid Id { get; private set; }
public HidePostCommand()
{
}
public HidePostCommand(string url) : this()
public HidePostCommand(Guid id) : this()
{
Url = url;
Id = id;
}
}
}

View File

@@ -1,6 +1,7 @@
using MediatR;
using System.Runtime.Serialization;
using Jambo.Application.Commands;
using System;
namespace Jambo.Application.Commands.Posts
{
@@ -8,16 +9,16 @@ namespace Jambo.Application.Commands.Posts
public class PublishPostCommand : IRequest
{
[DataMember]
public string Url { get; private set; }
public Guid Id { get; private set; }
public PublishPostCommand()
{
}
public PublishPostCommand(string url) : this()
public PublishPostCommand(Guid id) : this()
{
Url = url;
Id = id;
}
}
}

View File

@@ -0,0 +1,32 @@
using MediatR;
using System.Runtime.Serialization;
using Jambo.Application.Commands;
using System;
namespace Jambo.Application.Commands.Posts
{
[DataContract]
public class UpdatePostContentCommand : IRequest
{
[DataMember]
public Guid Id { get; private set; }
[DataMember]
public string Title { get; private set; }
[DataMember]
public string Content { get; private set; }
public UpdatePostContentCommand()
{
}
public UpdatePostContentCommand(Guid id, string title, string content) : this()
{
Id = id;
Title = title;
Content = content;
}
}
}

View File

@@ -4,14 +4,14 @@ using MediatR;
using System;
using System.Threading.Tasks;
namespace Jambo.Application.DomainEventHandlers
namespace Jambo.Application.DomainEventHandlers.Blogs
{
public class BlogCriadoEventHandler : IAsyncNotificationHandler<CreatedBlogDomainEvent>
public class BlogCreatedEventHandler : IAsyncNotificationHandler<BlogCreatedDomainEvent>
{
private readonly IBlogReadOnlyRepository _blogReadOnlyRepository;
private readonly IBlogWriteOnlyRepository _blogWriteOnlyRepository;
public BlogCriadoEventHandler(
public BlogCreatedEventHandler(
IBlogReadOnlyRepository blogReadOnlyRepository,
IBlogWriteOnlyRepository blogWriteOnlyRepository)
{
@@ -20,7 +20,7 @@ namespace Jambo.Application.DomainEventHandlers
_blogWriteOnlyRepository = blogWriteOnlyRepository ??
throw new ArgumentNullException(nameof(blogWriteOnlyRepository));
}
public async Task Handle(CreatedBlogDomainEvent message)
public async Task Handle(BlogCreatedDomainEvent message)
{
Blog blog = new Blog(message.AggregateRootId);

View File

@@ -0,0 +1,34 @@
using Jambo.Domain.Aggregates.Blogs;
using Jambo.Domain.Aggregates.Blogs.Events;
using MediatR;
using System;
using System.Threading.Tasks;
namespace Jambo.Application.DomainEventHandlers.Blogs
{
public class BlogDisabledEventHandler : IAsyncNotificationHandler<BlogUrlUpdatedDomainEvent>
{
private readonly IBlogReadOnlyRepository _blogReadOnlyRepository;
private readonly IBlogWriteOnlyRepository _blogWriteOnlyRepository;
public BlogDisabledEventHandler(
IBlogReadOnlyRepository blogReadOnlyRepository,
IBlogWriteOnlyRepository blogWriteOnlyRepository)
{
_blogReadOnlyRepository = blogReadOnlyRepository ??
throw new ArgumentNullException(nameof(blogReadOnlyRepository));
_blogWriteOnlyRepository = blogWriteOnlyRepository ??
throw new ArgumentNullException(nameof(blogWriteOnlyRepository));
}
public async Task Handle(BlogUrlUpdatedDomainEvent message)
{
Blog blog = await _blogReadOnlyRepository.GetBlog(message.AggregateRootId);
if (blog.Version == message.Version)
{
blog.Disable();
await _blogWriteOnlyRepository.UpdateBlog(blog);
}
}
}
}

View File

@@ -0,0 +1,34 @@
using Jambo.Domain.Aggregates.Blogs;
using Jambo.Domain.Aggregates.Blogs.Events;
using MediatR;
using System;
using System.Threading.Tasks;
namespace Jambo.Application.DomainEventHandlers.Blogs
{
public class BlogEnabledEventHandler : IAsyncNotificationHandler<BlogUrlUpdatedDomainEvent>
{
private readonly IBlogReadOnlyRepository _blogReadOnlyRepository;
private readonly IBlogWriteOnlyRepository _blogWriteOnlyRepository;
public BlogEnabledEventHandler(
IBlogReadOnlyRepository blogReadOnlyRepository,
IBlogWriteOnlyRepository blogWriteOnlyRepository)
{
_blogReadOnlyRepository = blogReadOnlyRepository ??
throw new ArgumentNullException(nameof(blogReadOnlyRepository));
_blogWriteOnlyRepository = blogWriteOnlyRepository ??
throw new ArgumentNullException(nameof(blogWriteOnlyRepository));
}
public async Task Handle(BlogUrlUpdatedDomainEvent message)
{
Blog blog = await _blogReadOnlyRepository.GetBlog(message.AggregateRootId);
if (blog.Version == message.Version)
{
blog.Enable();
await _blogWriteOnlyRepository.UpdateBlog(blog);
}
}
}
}

View File

@@ -4,14 +4,14 @@ using MediatR;
using System;
using System.Threading.Tasks;
namespace Jambo.Application.DomainEventHandlers
namespace Jambo.Application.DomainEventHandlers.Blogs
{
public class UrlDefinidaEventHandler : IAsyncNotificationHandler<BlogUrlUpdatedDomainEvent>
public class BlogUrlUpdatedEventHandler : IAsyncNotificationHandler<BlogUrlUpdatedDomainEvent>
{
private readonly IBlogReadOnlyRepository _blogReadOnlyRepository;
private readonly IBlogWriteOnlyRepository _blogWriteOnlyRepository;
public UrlDefinidaEventHandler(
public BlogUrlUpdatedEventHandler(
IBlogReadOnlyRepository blogReadOnlyRepository,
IBlogWriteOnlyRepository blogWriteOnlyRepository)
{

View File

@@ -0,0 +1,35 @@
using Jambo.Domain.Aggregates.Blogs;
using Jambo.Domain.Aggregates.Blogs.Events;
using Jambo.Domain.Aggregates.Posts;
using MediatR;
using System;
using System.Threading.Tasks;
namespace Jambo.Application.DomainEventHandlers.Posts
{
public class PostContentUpdatedEventHandler : IAsyncNotificationHandler<PostContentUpdatedDomainEvent>
{
private readonly IPostReadOnlyRepository _postReadOnlyRepository;
private readonly IPostWriteOnlyRepository _postWriteOnlyRepository;
public PostContentUpdatedEventHandler(
IPostReadOnlyRepository postReadOnlyRepository,
IPostWriteOnlyRepository postWriteOnlyRepository)
{
_postReadOnlyRepository = postReadOnlyRepository ??
throw new ArgumentNullException(nameof(postReadOnlyRepository));
_postWriteOnlyRepository = postWriteOnlyRepository ??
throw new ArgumentNullException(nameof(postWriteOnlyRepository));
}
public async Task Handle(PostContentUpdatedDomainEvent message)
{
Post post = await _postReadOnlyRepository.GetPost(message.AggregateRootId);
if (post.Version == message.Version)
{
post.UpdateContent(message.Title, message.Content);
await _postWriteOnlyRepository.UpdatePost(post);
}
}
}
}

View File

@@ -0,0 +1,31 @@
using Jambo.Domain.Aggregates.Blogs;
using Jambo.Domain.Aggregates.Blogs.Events;
using Jambo.Domain.Aggregates.Posts;
using MediatR;
using System;
using System.Threading.Tasks;
namespace Jambo.Application.DomainEventHandlers.Posts
{
public class PostCreatedEventHandler : IAsyncNotificationHandler<BlogCreatedDomainEvent>
{
private readonly IPostReadOnlyRepository _postReadOnlyRepository;
private readonly IPostWriteOnlyRepository _postWriteOnlyRepository;
public PostCreatedEventHandler(
IPostReadOnlyRepository postReadOnlyRepository,
IPostWriteOnlyRepository postWriteOnlyRepository)
{
_postReadOnlyRepository = postReadOnlyRepository ??
throw new ArgumentNullException(nameof(postReadOnlyRepository));
_postWriteOnlyRepository = postWriteOnlyRepository ??
throw new ArgumentNullException(nameof(postWriteOnlyRepository));
}
public async Task Handle(BlogCreatedDomainEvent message)
{
Post post = new Post(message.AggregateRootId);
await _postWriteOnlyRepository.AddPost(post);
}
}
}

View File

@@ -0,0 +1,35 @@
using Jambo.Domain.Aggregates.Blogs;
using Jambo.Domain.Aggregates.Blogs.Events;
using Jambo.Domain.Aggregates.Posts;
using MediatR;
using System;
using System.Threading.Tasks;
namespace Jambo.Application.DomainEventHandlers.Posts
{
public class PostDisabledEventHandler : IAsyncNotificationHandler<PostDisabledDomainEvent>
{
private readonly IPostReadOnlyRepository _postReadOnlyRepository;
private readonly IPostWriteOnlyRepository _postWriteOnlyRepository;
public PostDisabledEventHandler(
IPostReadOnlyRepository postReadOnlyRepository,
IPostWriteOnlyRepository postWriteOnlyRepository)
{
_postReadOnlyRepository = postReadOnlyRepository ??
throw new ArgumentNullException(nameof(postReadOnlyRepository));
_postWriteOnlyRepository = postWriteOnlyRepository ??
throw new ArgumentNullException(nameof(postWriteOnlyRepository));
}
public async Task Handle(PostDisabledDomainEvent message)
{
Post post = await _postReadOnlyRepository.GetPost(message.AggregateRootId);
if (post.Version == message.Version)
{
post.Disable();
await _postWriteOnlyRepository.UpdatePost(post);
}
}
}
}

View File

@@ -0,0 +1,36 @@
using Jambo.Domain.Aggregates.Blogs;
using Jambo.Domain.Aggregates.Blogs.Events;
using Jambo.Domain.Aggregates.Posts;
using MediatR;
using System;
using System.Threading.Tasks;
namespace Jambo.Application.DomainEventHandlers.Posts
{
public class PostEnabledEventHandler : IAsyncNotificationHandler<PostEnabledDomainEvent>
{
private readonly IPostReadOnlyRepository _postReadOnlyRepository;
private readonly IPostWriteOnlyRepository _postWriteOnlyRepository;
public PostEnabledEventHandler(
IPostReadOnlyRepository postReadOnlyRepository,
IPostWriteOnlyRepository postWriteOnlyRepository)
{
_postReadOnlyRepository = postReadOnlyRepository ??
throw new ArgumentNullException(nameof(postReadOnlyRepository));
_postWriteOnlyRepository = postWriteOnlyRepository ??
throw new ArgumentNullException(nameof(postWriteOnlyRepository));
}
public async Task Handle(PostEnabledDomainEvent message)
{
Post post = await _postReadOnlyRepository.GetPost(message.AggregateRootId);
if (post.Version == message.Version)
{
post.Enable();
await _postWriteOnlyRepository.UpdatePost(post);
}
}
}
}

View File

@@ -0,0 +1,35 @@
using Jambo.Domain.Aggregates.Blogs;
using Jambo.Domain.Aggregates.Blogs.Events;
using Jambo.Domain.Aggregates.Posts;
using MediatR;
using System;
using System.Threading.Tasks;
namespace Jambo.Application.DomainEventHandlers.Posts
{
public class PostHiddenDomainEventHandler : IAsyncNotificationHandler<PostHiddenDomainEvent>
{
private readonly IPostReadOnlyRepository _postReadOnlyRepository;
private readonly IPostWriteOnlyRepository _postWriteOnlyRepository;
public PostHiddenDomainEventHandler(
IPostReadOnlyRepository postReadOnlyRepository,
IPostWriteOnlyRepository postWriteOnlyRepository)
{
_postReadOnlyRepository = postReadOnlyRepository ??
throw new ArgumentNullException(nameof(postReadOnlyRepository));
_postWriteOnlyRepository = postWriteOnlyRepository ??
throw new ArgumentNullException(nameof(postWriteOnlyRepository));
}
public async Task Handle(PostHiddenDomainEvent message)
{
Post post = await _postReadOnlyRepository.GetPost(message.AggregateRootId);
if (post.Version == message.Version)
{
post.Hide();
await _postWriteOnlyRepository.UpdatePost(post);
}
}
}
}

View File

@@ -0,0 +1,35 @@
using Jambo.Domain.Aggregates.Blogs;
using Jambo.Domain.Aggregates.Blogs.Events;
using Jambo.Domain.Aggregates.Posts;
using MediatR;
using System;
using System.Threading.Tasks;
namespace Jambo.Application.DomainEventHandlers.Posts
{
public class PostPublishedDomainEventHandler : IAsyncNotificationHandler<PostPublishedDomainEvent>
{
private readonly IPostReadOnlyRepository _postReadOnlyRepository;
private readonly IPostWriteOnlyRepository _postWriteOnlyRepository;
public PostPublishedDomainEventHandler(
IPostReadOnlyRepository postReadOnlyRepository,
IPostWriteOnlyRepository postWriteOnlyRepository)
{
_postReadOnlyRepository = postReadOnlyRepository ??
throw new ArgumentNullException(nameof(postReadOnlyRepository));
_postWriteOnlyRepository = postWriteOnlyRepository ??
throw new ArgumentNullException(nameof(postWriteOnlyRepository));
}
public async Task Handle(PostPublishedDomainEvent message)
{
Post post = await _postReadOnlyRepository.GetPost(message.AggregateRootId);
if (post.Version == message.Version)
{
post.Publish();
await _postWriteOnlyRepository.UpdatePost(post);
}
}
}
}

View File

@@ -3,6 +3,7 @@ using System;
using System.Collections.Generic;
using MongoDB.Driver;
using Jambo.Domain.Aggregates.Blogs;
using Jambo.Domain.Aggregates.Posts;
namespace Jambo.Application.Queries
{

View File

@@ -1,4 +1,5 @@
using Jambo.Domain.Aggregates.Blogs.Events;
using Jambo.Domain.Aggregates.Posts;
using System;
using System.Collections.Generic;
@@ -8,11 +9,10 @@ namespace Jambo.Domain.Aggregates.Blogs
{
public string Url { get; private set; }
public int Rating { get; private set; }
public List<Post> Posts { get; private set; }
public Blog()
{
AddEvent(new CreatedBlogDomainEvent(Id));
AddEvent(new BlogCreatedDomainEvent(Id));
}
public Blog(Guid id)
@@ -28,12 +28,12 @@ namespace Jambo.Domain.Aggregates.Blogs
public void Disable()
{
AddEvent(new DisabledBlogDomainEvent(Id, Version));
AddEvent(new BlogDisabledDomainEvent(Id, Version));
}
public void Enable()
{
AddEvent(new EnabledBlogDomainEvent(Id, Version));
AddEvent(new BlogEnabledDomainEvent(Id, Version));
}
}
}

View File

@@ -3,9 +3,9 @@ using System;
namespace Jambo.Domain.Aggregates.Blogs.Events
{
public class CreatedBlogDomainEvent : DomainEvent
public class BlogCreatedDomainEvent : DomainEvent
{
public CreatedBlogDomainEvent(Guid aggregateRootId)
public BlogCreatedDomainEvent(Guid aggregateRootId)
:base(aggregateRootId, 0)
{
}

View File

@@ -3,9 +3,9 @@ using System;
namespace Jambo.Domain.Aggregates.Blogs.Events
{
public class DisabledBlogDomainEvent : DomainEvent
public class BlogDisabledDomainEvent : DomainEvent
{
public DisabledBlogDomainEvent(Guid aggregateRootId, int version)
public BlogDisabledDomainEvent(Guid aggregateRootId, int version)
:base(aggregateRootId, version)
{
}

View File

@@ -3,9 +3,9 @@ using System;
namespace Jambo.Domain.Aggregates.Blogs.Events
{
public class EnabledBlogDomainEvent : DomainEvent
public class BlogEnabledDomainEvent : DomainEvent
{
public EnabledBlogDomainEvent(Guid aggregateRootId, int version)
public BlogEnabledDomainEvent(Guid aggregateRootId, int version)
:base(aggregateRootId, version)
{
}

View File

@@ -1,10 +0,0 @@
namespace Jambo.Domain.Aggregates.Blogs
{
public class Post : Entity
{
public string Title { get; private set; }
public string Content { get; private set; }
public int BlogId { get; private set; }
public Blog Blog { get; private set; }
}
}

View File

@@ -3,16 +3,15 @@ using System;
namespace Jambo.Domain.Aggregates.Blogs.Events
{
public class CreatedPostDomainEvent: DomainEvent
public class PostContentUpdatedDomainEvent : DomainEvent
{
public string Title { get; set; }
public string Content { get; set; }
public CreatedPostDomainEvent(Guid aggregateRootId, int version,
public PostContentUpdatedDomainEvent(Guid aggregateRootId, int version,
string title, string content)
: base(aggregateRootId, version)
{
AggregateRootId = aggregateRootId;
Title = title;
Content = content;
}

View File

@@ -0,0 +1,13 @@
using Jambo.Domain.ServiceBus;
using System;
namespace Jambo.Domain.Aggregates.Blogs.Events
{
public class PostCreatedDomainEvent : DomainEvent
{
public PostCreatedDomainEvent(Guid aggregateRootId)
:base(aggregateRootId, 0)
{
}
}
}

View File

@@ -0,0 +1,14 @@
using Jambo.Domain.ServiceBus;
using System;
namespace Jambo.Domain.Aggregates.Blogs.Events
{
public class PostDisabledDomainEvent : DomainEvent
{
public PostDisabledDomainEvent(Guid aggregateRootId, int version)
: base(aggregateRootId, version)
{
}
}
}

View File

@@ -0,0 +1,14 @@
using Jambo.Domain.ServiceBus;
using System;
namespace Jambo.Domain.Aggregates.Blogs.Events
{
public class PostEnabledDomainEvent : DomainEvent
{
public PostEnabledDomainEvent(Guid aggregateRootId, int version)
: base(aggregateRootId, version)
{
}
}
}

View File

@@ -0,0 +1,13 @@
using Jambo.Domain.ServiceBus;
using System;
namespace Jambo.Domain.Aggregates.Blogs.Events
{
public class PostHiddenDomainEvent : DomainEvent
{
public PostHiddenDomainEvent(Guid aggregateRootId, int version)
: base(aggregateRootId, version)
{
}
}
}

View File

@@ -0,0 +1,13 @@
using Jambo.Domain.ServiceBus;
using System;
namespace Jambo.Domain.Aggregates.Blogs.Events
{
public class PostPublishedDomainEvent : DomainEvent
{
public PostPublishedDomainEvent(Guid aggregateRootId, int version)
: base(aggregateRootId, version)
{
}
}
}

View File

@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Jambo.Domain.Aggregates.Posts
{
public interface IPostReadOnlyRepository
{
Task<IEnumerable<Post>> GetBlogPosts(Guid blogId);
Task<Post> GetPost(Guid id);
}
}

View File

@@ -0,0 +1,10 @@
using System.Threading.Tasks;
namespace Jambo.Domain.Aggregates.Posts
{
public interface IPostWriteOnlyRepository
{
Task AddPost(Post post);
Task UpdatePost(Post post);
}
}

View File

@@ -0,0 +1,55 @@
using Jambo.Domain.Aggregates.Blogs.Events;
using System;
namespace Jambo.Domain.Aggregates.Posts
{
public class Post : AggregateRoot
{
public string Title { get; private set; }
public string Content { get; private set; }
public int BlogId { get; private set; }
public Post()
{
AddEvent(new PostCreatedDomainEvent(Id));
}
public Post(Guid id)
:base(id)
{
}
public void Disable()
{
AddEvent(new PostDisabledDomainEvent(Id, Version));
}
public void Hide()
{
AddEvent(new PostHiddenDomainEvent(Id, Version));
}
public void Enable()
{
AddEvent(new PostEnabledDomainEvent(Id, Version));
}
public void UpdateContent(string title, string content)
{
Title = title;
Content = content;
AddEvent(new PostContentUpdatedDomainEvent(Id, Version, Title, Content));
}
public void Publish()
{
AddEvent(new PostPublishedDomainEvent(Id, Version));
}
public void SetBlogId(Guid blogId)
{
throw new NotImplementedException();
}
}
}

View File

@@ -1,4 +1,5 @@
using Jambo.Domain.Aggregates.Blogs;
using Jambo.Domain.Aggregates.Posts;
using MongoDB.Driver;
namespace Jambo.Infrastructure

View File

@@ -1,10 +1,11 @@
using Jambo.Domain.Aggregates.Blogs;
using Jambo.Domain.Aggregates.Posts;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Jambo.Infrastructure.Repositories
namespace Jambo.Infrastructure.Repositories.Blogs
{
public class BlogReadOnlyRepository : IBlogReadOnlyRepository
{

View File

@@ -3,7 +3,7 @@ using MongoDB.Driver;
using System;
using System.Threading.Tasks;
namespace Jambo.Infrastructure.Repositories
namespace Jambo.Infrastructure.Repositories.Blogs
{
public class BlogWriteOnlyRepository : IBlogWriteOnlyRepository
{

View File

@@ -0,0 +1,29 @@
using Jambo.Domain.Aggregates.Blogs;
using Jambo.Domain.Aggregates.Posts;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Jambo.Infrastructure.Repositories.Posts
{
public class PostReadOnlyRepository : IPostReadOnlyRepository
{
private readonly MongoContext _mongoContext;
public PostReadOnlyRepository(MongoContext mongoContext)
{
_mongoContext = mongoContext;
}
public async Task<IEnumerable<Post>> GetBlogPosts(Guid blogId)
{
throw new NotImplementedException();
}
public async Task<Post> GetPost(Guid id)
{
return await _mongoContext.Posts.Find(e => e.Id == id).SingleOrDefaultAsync();
}
}
}

View File

@@ -0,0 +1,28 @@
using Jambo.Domain.Aggregates.Blogs;
using Jambo.Domain.Aggregates.Posts;
using MongoDB.Driver;
using System;
using System.Threading.Tasks;
namespace Jambo.Infrastructure.Repositories.Posts
{
public class PostWriteOnlyRepository : IPostWriteOnlyRepository
{
private readonly MongoContext _mongoContext;
public PostWriteOnlyRepository(MongoContext mongoContext)
{
_mongoContext = mongoContext;
}
public async Task AddPost(Post post)
{
await _mongoContext.Posts.InsertOneAsync(post);
}
public async Task UpdatePost(Post post)
{
post.Version += 1;
await _mongoContext.Posts.ReplaceOneAsync(e => e.Id == post.Id, post);
}
}
}