Skip to content

Instantly share code, notes, and snippets.

@JefClaes
Created April 12, 2013 22:16
Show Gist options
  • Save JefClaes/5375605 to your computer and use it in GitHub Desktop.
Save JefClaes/5375605 to your computer and use it in GitHub Desktop.
Best attempt at four eyes principal
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using Ninject;
namespace ModelingFourEyes
{
class Program
{
static void Main(string[] args)
{
var kernel = new StandardKernel();
kernel.Bind<IRequestHandler<AddPersonRequestContent>>().To<AddPersonRequestHandler>();
var request = new Request(
new JsonContentSerializer(),
new RequestHeaders(new User("JefClaes")),
new AddPersonRequestContent() { FirstName = "Kristien", LastName = "Behets" });
var requestCoordinator = new RequestCoordinator(
new InMemoryTransientRequestRepository(), kernel);
requestCoordinator.Create(request);
requestCoordinator.Accept(request.Id, new User("PowerUser"));
Console.ReadLine();
}
public class AddPersonRequestHandler : IRequestHandler<AddPersonRequestContent>
{
public void OnAccepted(AddPersonRequestContent requestContent)
{
Console.WriteLine("Accepted " + requestContent.FirstName);
Console.WriteLine("Accepted " + requestContent.LastName);
}
}
public class RequestCoordinator
{
private IRequestRepository _requestRepository;
private IKernel _kernel;
public RequestCoordinator(IRequestRepository requestRepository, IKernel kernel)
{
_requestRepository = requestRepository;
_kernel = kernel;
}
public void Create(Request request)
{
_requestRepository.Add(request);
}
public void Accept(Guid id, User supervisingUser)
{
var request = _requestRepository.GetById(id);
var requestHandlerType = typeof(IRequestHandler<>).MakeGenericType(request.ContentType);
foreach (var requestHandler in _kernel.GetAll(requestHandlerType))
{
((dynamic)requestHandler).OnAccepted((dynamic)request.GetContent());
}
}
public void Decline(Guid id, User supervisingUser)
{
var request = _requestRepository.GetById(id);
request.Decline(supervisingUser);
}
}
public class InMemoryTransientRequestRepository : IRequestRepository
{
private readonly List<Request> _requests = new List<Request>();
public void Add(Request request)
{
_requests.Add(request);
}
public Request GetById(Guid id)
{
return _requests.Where(x => x.Id == id).SingleOrDefault();
}
}
public interface IRequestRepository
{
void Add(Request request);
Request GetById(Guid id);
}
public interface IRequestHandler<TRequestContent>
{
void OnAccepted(TRequestContent requestContent);
}
public interface IContentSerializer
{
string Serialize(object content);
object Deserialize(Type type, string content);
}
public class JsonContentSerializer : IContentSerializer
{
public string Serialize(object content)
{
return JsonConvert.SerializeObject(content);
}
public object Deserialize(Type type, string content)
{
return JsonConvert.DeserializeObject(content, type);
}
}
public class Request
{
private IContentSerializer _contentSerializer;
public Request(IContentSerializer contentSerializer, RequestHeaders headers, object content) : this(contentSerializer)
{
Id = Guid.NewGuid();
Headers = headers;
ContentType = content.GetType();
RawContent = _contentSerializer.Serialize(content);
}
public Request(IContentSerializer contentSerializer)
{
_contentSerializer = contentSerializer;
}
private string RawContent { get; set; }
public Guid Id { get; private set; }
public RequestHeaders Headers { get; private set; }
public Type ContentType { get; private set; }
public object GetContent()
{
return _contentSerializer.Deserialize(ContentType, RawContent);
}
public void Accept(User supervisingUser)
{
Headers.ChangeStatus(SupervisionStatus.Accepted, supervisingUser);
}
public void Decline(User supervisingUser)
{
Headers.ChangeStatus(SupervisionStatus.Declined, supervisingUser);
}
}
public class RequestHeaders
{
public RequestHeaders(User requestingUser)
{
RequestingUser = requestingUser;
RequestedOn = DateTime.Now;
Status = SupervisionStatus.Waiting;
}
public User RequestingUser { get; private set; }
public DateTime RequestedOn { get; private set; }
public User SupervisingUser { get; private set; }
public DateTime SupervisedOn { get; private set; }
public SupervisionStatus Status { get; private set; }
public void ChangeStatus(SupervisionStatus status, User supervisingUser)
{
if (status == SupervisionStatus.Waiting)
throw new InvalidOperationException("The status shouldn't be changed to waiting after creation.");
Status = status;
SupervisingUser = supervisingUser;
SupervisedOn = DateTime.Now;
}
}
public enum SupervisionStatus
{
Waiting = 0,
Accepted = 1,
Declined = 2
}
public class AddPersonRequestContent
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Person
{
public Person(string firstName, string lastName)
{
Guard.ForEmpty(firstName, "first name");
Guard.ForEmpty(lastName, "last name");
FirstName = firstName;
LastName = lastName;
}
private string FirstName { get; set; }
private string LastName { get; set; }
}
public class User
{
public User(string userId)
{
UserId = userId;
}
public string UserId { get; private set; }
}
public class Guard
{
public static void ForEmpty(string value, string desc)
{
if (string.IsNullOrEmpty(value))
throw new ArgumentNullException(desc);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment