Skip to content

Instantly share code, notes, and snippets.

@dbones
Created November 27, 2021 18:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dbones/49552ed501231b38b5eb887b63f5b910 to your computer and use it in GitHub Desktop.
Save dbones/49552ed501231b38b5eb887b63f5b910 to your computer and use it in GitHub Desktop.
example of duplicate/redundant code (to prove a point)
namespace PipesExample
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
/// <summary>
/// an example of commands which have more than one concern, leading to boiler plate code
/// this is before we implement a project such as Pipes
/// </summary>
class Program
{
static async Task Main(string[] args)
{
var container = SetupContainer.Build();
using var appScope = container.CreateScope();
await RunApp(appScope.ServiceProvider);
}
static async Task RunApp(IServiceProvider container)
{
var firstTransferCommand = container.GetService<ICommand<Transfer>>();
await firstTransferCommand.Execute(new Transfer()
{
Amount = 10.00m,
//SourceAccountId = "a1",
DestinationAccountId = "a2"
});
var secondTransferCommand = container.GetService<ICommand<ChangeAddress>>();
await secondTransferCommand.Execute(new ChangeAddress()
{
AccountId = "a1",
NewAddress = "this is a new address"
});
}
}
public interface ICommand<in TMessage>
{
Task Execute(TMessage message);
}
internal class ChangeAddressCommand : ICommand<ChangeAddress>
{
private readonly Logger _logger;
public ChangeAddressCommand(Logger logger)
{
_logger = logger;
}
public Task Execute(ChangeAddress changeAddress)
{
var stopwatch = new Stopwatch();
stopwatch.Start();
try
{
var validationContext = new ValidationContext(changeAddress);
var validationResults = new List<ValidationResult>();
if (!Validator.TryValidateObject(changeAddress, validationContext, validationResults, true))
{
var message = string.Join(Environment.NewLine, validationResults.Select(x => x.ErrorMessage));
throw new ValidationException(message);
}
//do some logic here. (this is the core logic)
_logger.Log($"updated address for {changeAddress.AccountId}, " +
$"to {changeAddress.NewAddress}");
}
catch (Exception e)
{
_logger.Log(e);
throw;
}
stopwatch.Stop();
_logger.Log(stopwatch.Elapsed.ToString());
return Task.CompletedTask;
}
}
internal class TransferCommand : ICommand<Transfer>
{
private readonly Logger _logger;
public TransferCommand(Logger logger)
{
_logger = logger;
}
public virtual Task Execute(Transfer transfer)
{
var stopwatch = new Stopwatch();
stopwatch.Start();
try
{
var validationContext = new ValidationContext(transfer);
var validationResults = new List<ValidationResult>();
if (!Validator.TryValidateObject(transfer, validationContext, validationResults, true))
{
var message = string.Join(Environment.NewLine, validationResults.Select(x => x.ErrorMessage));
throw new ValidationException(message);
}
//do some logic here.
Console.WriteLine($"Transfering {transfer.Amount}, " +
$"from: {transfer.SourceAccountId} " +
$"to {transfer.DestinationAccountId}");
}
catch (Exception e)
{
_logger.Log(e);
throw;
}
stopwatch.Stop();
_logger.Log(stopwatch.Elapsed.ToString());
return Task.CompletedTask;
}
}
internal class Transfer
{
public decimal Amount { get; set; }
[Required]
public string SourceAccountId { get; set; }
[Required]
public string DestinationAccountId { get; set; }
}
internal class ChangeAddress
{
[Required]
public string AccountId { get; set; }
[Required]
public string NewAddress { get; set; }
}
/// <summary>
/// a place to setup the container, consider the .NET HostBuilder
/// </summary>
internal static class SetupContainer
{
internal static IServiceProvider Build()
{
var collection = new ServiceCollection();
collection.AddSingleton<Logger>(); //use the dotnet one
collection.AddScoped<ICommand<Transfer>, TransferCommand>();
collection.AddScoped<ICommand<ChangeAddress>, ChangeAddressCommand>();
return collection.BuildServiceProvider();
}
}
/// <summary>
/// simple console logger, please use the .NET out of the box
/// </summary>
internal class Logger
{
public void Log(string message)
{
Console.WriteLine(message);
}
public void Log(Exception e)
{
Console.WriteLine(e);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment