Rovani's Sandbox

Rovani's Sandbox

About Me
Projects
If you like what you see (view the About Me page for more) and you're interested in exploring opportunities for us to partner up, please reach out to me at david@rovani.net or message me on LinkedIn #OpenToWork

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
    {
    }
}