Created
April 12, 2013 22:16
-
-
Save JefClaes/5375605 to your computer and use it in GitHub Desktop.
Best attempt at four eyes principal
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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