Skip to content

Commit

Permalink
ADVANCED RELATIONS
Browse files Browse the repository at this point in the history
  • Loading branch information
SonicTheCat committed Mar 13, 2019
1 parent 6f0ae00 commit cf03922
Show file tree
Hide file tree
Showing 40 changed files with 1,136 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace P01_BillsPaymentSystem.Core.Attributes
{
using System;

public class InjectAttribute : Attribute
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
namespace P01_BillsPaymentSystem.Core
{
using P01_BillsPaymentSystem.Core.Attributes;
using P01_BillsPaymentSystem.Core.Commands.Contracts;
using P01_BillsPaymentSystem.Core.Contracts;

using System;
using System.Linq;
using System.Reflection;

public class CommandInterpreter : ICommandInterpreter
{
private const string suffix = "Command";

private readonly IServiceProvider serviceProvider;

public CommandInterpreter(IServiceProvider serviceProvider)
{
this.serviceProvider = serviceProvider;
}

public IExecutable InterpretCommand(string[] data)
{
var commandType = data[0] + suffix;
data = data.Skip(1).ToArray();

Assembly assembly = Assembly.GetCallingAssembly();
var model = assembly.GetTypes().FirstOrDefault(x => x.Name == commandType);

if (model == null)
{
throw new ArgumentException("Invalid type!");
}

PropertyInfo[] propertiesToInject = model
.GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(p => p.GetCustomAttributes<InjectAttribute>().Any())
.ToArray();

var injectProps = propertiesToInject
.Select(p => this.serviceProvider.GetService(p.PropertyType))
.ToArray();

var joinedParams = new object[] { data }.Concat(injectProps).ToArray();

IExecutable command = (IExecutable)Activator.CreateInstance(model, joinedParams);

return command;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace P01_BillsPaymentSystem.Core.Commands
{
using P01_BillsPaymentSystem.Core.Commands.Contracts;

public abstract class Command : IExecutable
{
public Command(string[] data)
{
this.Data = data;
}

public string[] Data { get; protected set; }

public abstract void Execute();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace P01_BillsPaymentSystem.Core.Commands.Contracts
{
public interface IExecutable
{
void Execute();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
namespace P01_BillsPaymentSystem.Core.Commands
{
using Attributes;
using IO.Contracts;
using P01_BillsPaymentSystem.Data;

public class PayBillsCommand : Command
{
public PayBillsCommand(string[] data, IUnitOfWork unitOfWork, IReader reader, IWriter writer)
: base(data)
{
this.UnitOfWork = unitOfWork;
this.Reader = reader;
this.Writer = writer;
}

[Inject]
public IUnitOfWork UnitOfWork { get; set; }

[Inject]
public IReader Reader { get; set; }

[Inject]
public IWriter Writer { get; set; }

public override void Execute()
{
var id = int.Parse(this.Data[0]);
var amount = decimal.Parse(this.Data[1]);

this.Writer.WriteLine(OutputMessages.Loading);
var reuslt = this.UnitOfWork.Users.PayBills(id, amount);
this.Writer.WriteLine(reuslt);

this.UnitOfWork.Complete();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
namespace P01_BillsPaymentSystem.Core.Commands
{
using Attributes;
using IO.Contracts;
using P01_BillsPaymentSystem.Data;

public class UserInfoCommand : Command
{
public UserInfoCommand(string[] data, IUnitOfWork unitOfWork, IReader reader, IWriter writer)
: base(data)
{
this.UnitOfWork = unitOfWork;
this.Reader = reader;
this.Writer = writer;
}

[Inject]
public IUnitOfWork UnitOfWork { get; set; }

[Inject]
public IReader Reader { get; set; }

[Inject]
public IWriter Writer { get; set; }

public override void Execute()
{
var id = int.Parse(this.Data[0]);

this.Writer.WriteLine(OutputMessages.Loading);
var reuslt = this.UnitOfWork.Users.GetUserAndAllPayments(id);
this.Writer.WriteLine(reuslt);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace P01_BillsPaymentSystem.Core.Contracts
{
using P01_BillsPaymentSystem.Core.Commands.Contracts;

public interface ICommandInterpreter
{
IExecutable InterpretCommand(string[] data);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace P01_BillsPaymentSystem.Core.Contracts
{
public interface IEngine
{
void Run();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
namespace P01_BillsPaymentSystem.Core
{
using System;

using Contracts;
using P01_BillsPaymentSystem.Core.IO.Contracts;

public class Engine : IEngine
{
private readonly IReader reader;
private readonly IWriter writer;
private readonly ICommandInterpreter commandInterpreter;

public Engine(IReader reader, IWriter writer, ICommandInterpreter commandInterpreter)
{
this.reader = reader;
this.writer = writer;
this.commandInterpreter = commandInterpreter;
}

public void Run()
{
this.writer.WriteLine(OutputMessages.WelcomeString());

while (true)
{
try
{
this.writer.WriteLine(OutputMessages.MenuOptions());

var result = string.Empty;
var input = this.reader.ReadLine().Split();

var command = this.commandInterpreter.InterpretCommand(input);
command.Execute();
}
catch (Exception)
{
this.writer.WriteLine(OutputMessages.InvalidCommand);
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace P01_BillsPaymentSystem.Core.IO
{
using System;

using Contracts;

public class ConsoleReader : IReader
{
public string ReadLine()
{
return Console.ReadLine();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace P01_BillsPaymentSystem.Core.IO
{
using System;

using Contracts;

public class ConsoleWriter : IWriter
{
public void WriteLine(string text)
{
Console.WriteLine(text);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace P01_BillsPaymentSystem.Core.IO.Contracts
{
public interface IReader
{
string ReadLine();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace P01_BillsPaymentSystem.Core.IO.Contracts
{
public interface IWriter
{
void WriteLine(string text);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
namespace P01_BillsPaymentSystem.Core
{
using System.Text;

public static class OutputMessages
{
public static string EnterId => "Enter userId: ";

public static string Loading => "Loading...";

public static string InvalidCommand=> "Invalid Command! Try again";

public static string EnterIdAndAmount => "Enter userId and bills amount separated by white space: ";

public static string WelcomeString() => "Welcome to our BillPaymentSystem. Please choose one of the following options from the menu!";

public static string MenuOptions()
{
StringBuilder sb = new StringBuilder();
sb.AppendLine();
sb.AppendLine("Type 'UserInfo {id}' to see specific information about a user");
sb.AppendLine("Type 'PayBills {id} {billsAmount}' to try pay bills for a user");

return sb.ToString();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="2.2.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\P01_BillsPaymentSystem.Data\P01_BillsPaymentSystem.Data.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
namespace P01_BillsPaymentSystem.Data.Models.Attributes
{
using System;
using System.ComponentModel.DataAnnotations;

[AttributeUsage(AttributeTargets.Property)]
public class XorAttribute : ValidationAttribute
{
private readonly string targetAttribute;

public XorAttribute(string targetAttribute)
{
this.targetAttribute = targetAttribute;
}

protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var property = validationContext.ObjectType
.GetProperty(targetAttribute)
.GetValue(validationContext.ObjectInstance);

if ((property == null && value != null) || (property != null && value == null))
{
return ValidationResult.Success;
}

return new ValidationResult("One of the props must be null!");
}
}
}
Loading

0 comments on commit cf03922

Please sign in to comment.