

[DataContract(Name = "857d960c-4b91-49cc-98fd-fa543906c52d")]
public class CreateTask : ICommand
{
public CreateTask() { }
public CreateTask(TaskId id, UserId userId, string name, DateTimeOffset timestamp
{
if (id is null) throw new ArgumentNullException(nameof(id));
if (userId is null) throw new ArgumentNullException(nameof(userId));
if (name is null) throw new ArgumentNullException(nameof(name));
if (timestamp == default) throw new ArgumentNullException(nameof(timestamp));
Id = id;
UserId = userId;
Name = name;
Timestamp = timestamp;
}
[DataMember(Order = 1)]
public TaskId Id { get; private set; }
[DataMember(Order = 2)]
public UserId UserId { get; private set; }
[DataMember(Order = 3)]
public string Name { get; private set; }
[DataMember(Order = 4)]
public DateTimeOffset Timestamp { get; private set; }
public override string ToString()
{
return $"Create a task with id '{Id}' and name '{Name}' for user [{UserId}].";
}
}[DataContract(Name = "728fc4e7-628b-4962-bd68-97c98aa05694")]
public class TaskCreated : IEvent
{
TaskCreated() { }
public TaskCreated(TaskId id, UserId userId, string name, DateTimeOffset timestamp)
{
Id = id;
UserId = userId;
Name = name;
CreatedAt = DateTimeOffset.UtcNow;
Timestamp = timestamp;
}
[DataMember(Order = 1)]
public TaskId Id { get; private set; }
[DataMember(Order = 2)]
public UserId UserId { get; private set; }
[DataMember(Order = 3)]
public string Name { get; private set; }
[DataMember(Order = 4)]
public DateTimeOffset CreatedAt { get; private set; }
[DataMember(Order = 5)]
public DateTimeOffset Timestamp { get; private set; }
public override string ToString()
{
return $"Task with id '{Id}' and name '{Name}' for user [{UserId}] at {CreatedAt} has been created.";
}
}public class TaskAggregate : AggregateRoot<TaskState>
{
public TaskAggregate() { }
public void CreateTask(TaskId id, UserId userId, string name, DateTimeOffset deadline)
{
IEvent @event = new TaskCreated(id, userId, name, deadline);
Apply(@event);
}
}public class TaskState : AggregateRootState<TaskAggregate, TaskId>
{
public override TaskId Id { get; set; }
public UserId UserId { get; set; }
public string Name { get; set; }
public DateTimeOffset CreatedAt { get; set; }
public DateTimeOffset Deadline { get; set; }
public void When(TaskCreated @event)
{
Id = @event.Id;
UserId = @event.UserId;
Name = @event.Name;
CreatedAt = @event.CreatedAt;
Deadline = @event.Timestamp;
}
}[DataContract(Name = "ef669879-5d35-4cb7-baea-39a7c46c9e13")]
public class TaskService : ApplicationService<TaskAggregate>,
ICommandHandler<CreateTask>
{
public TaskService(IAggregateRepository repository) : base(repository) { }
public async Task HandleAsync(CreateTask command)
{
ReadResult<TaskAggregate> taskResult = await repository.LoadAsync<TaskAggregate>(command.Id).ConfigureAwait(false);
if (taskResult.NotFound)
{
var task = new TaskAggregate();
task.CreateTask(command.Id, command.UserId, command.Name, DateTimeOffset.UtcNow);
await repository.SaveAsync(task).ConfigureAwait(false);
}
}
}[ApiController]
[Route("[controller]/[action]")]
public class TaskController : ControllerBase
{
private readonly IPublisher<ICommand> _publisher;
public TaskController(IPublisher<ICommand> publisher)
{
_publisher = publisher;
}
[HttpPost]
public IActionResult CreateTask(CreateTaskRequest request)
{
string id = Guid.NewGuid().ToString();
string Userid = Guid.NewGuid().ToString();
TaskId taskId = new TaskId(id);
UserId userId = new UserId(Userid);
var expireDate = DateTimeOffset.UtcNow;
expireDate.AddDays(request.DaysActive);
CreateTask command = new CreateTask(taskId, userId, request.Name, expireDate);
if (_publisher.Publish(command) == false)
{
return Problem($"Unable to publish command. {command.Id}: {command.Name}");
};
return Ok(id);
}
}public class CreateTaskRequest
{
[Required]
public string Name { get; set; }
[Required]
public int DaysActive { get; set; }
}