User* Can Create** New Patron***
The first thing that I learned with Dependency Injection is that it encourages a mindset of "I'll figure that out that later." This allows me to put in the bare minimum for what might pass a test, even though I know it will have all kinds of complex integration somewhere down the line. To start this little experiment, I am going to put together a tiny amount of arguably functional code. I will start with the very simple definition of what a User is, what it means to Create an entity, and how a Patron is represented.
*"User"
A "User" in this case is the arbitrary creator of a command and consumer of the factory. For now, the User is the test suite (powered by xUnit).
using Moq;
using System;
using Vigil.Domain;
using Vigil.MessageQueue;
using Vigil.MessageQueue.Commands;
using Xunit;
namespace Vigil.Patrons
{
public class PatronFactoryTest
{
[Fact]
public void User_Can_Create_New_Patron()
{
var queue = new Mock<ICommandQueue>(MockBehavior.Strict);
queue.Setup(q => q.QueueCommand(It.IsAny<ICommand>(), It.IsAny<IKeyIdentity>())).Verifiable();
PatronFactory factory = new PatronFactory(queue.Object);
IKeyIdentity result = factory.CreatePatron(new CreatePatronCommand()
{
DisplayName = "Test User",
IsAnonymous = false,
PatronType = "Test Account"
});
queue.VerifyAll();
Assert.NotEqual(Guid.Empty, result.Id);
}
}
}
**"Create"
At this point, I am going to define Create as issuing the command to something else to instantiate and persist a new representation of the entity.
using System.Diagnostics.Contracts;
using Vigil.Domain;
using Vigil.MessageQueue;
using Vigil.MessageQueue.Commands;
namespace Vigil.Patrons
{
public class PatronFactory
{
protected readonly ICommandQueue _queue;
public PatronFactory(ICommandQueue queue)
{
_queue = queue;
}
public IKeyIdentity CreatePatron(CreatePatronCommand command)
{
Contract.Requires(command != null);
Contract.Ensures(Contract.Result<IKeyIdentity>() != null);
var key = KeyIdentity.NewIdentity();
_queue.QueueCommand(command, key);
return key;
}
}
}
***"Patron"
A patron, this early in development, is an abstract representation of what should be created - it does not care about persistence or structure.
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using Vigil.Domain;
namespace Vigil.MessageQueue.Commands
{
public class CreatePatronCommand : ICommand
{
[Required, StringLength(250)]
public string DisplayName { get; set; }
[DefaultValue(false)]
public bool IsAnonymous { get; set; } = false;
[Required, StringLength(250)]
public string PatronType { get; set; }
}
}
ICommandQueue Interface
The most basic, simple interface with the bare minimum for what a message queue would need to implement.
using Vigil.Domain;
namespace Vigil.MessageQueue
{
public interface ICommandQueue
{
void QueueCommand(ICommand command, IKeyIdentity key);
}
}
ICommand Interface
This is just a simple way to identify commands and provide a way for future restrictions and contracts, when I need them.
namespace Vigil.Domain
{
public interface ICommand
{
}
}