Rovani's Sandbox

Rovani's Sandbox

About Me
Projects

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