Skip to content

Instantly share code, notes, and snippets.

@detroitpro
Created December 9, 2016 22:12
Show Gist options
  • Save detroitpro/81d4e82edbd1ce8b44e53a1e1eb1ded2 to your computer and use it in GitHub Desktop.
Save detroitpro/81d4e82edbd1ce8b44e53a1e1eb1ded2 to your computer and use it in GitHub Desktop.
Need help rebuilding commands and executing them. Ideas?
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq.Expressions;
using System.Threading.Tasks;
using FluentAssertions;
using NUnit.Framework;
namespace Commander
{
public class Tests
{
[Test]
public async Task Test()
{
var general = new General();
Response<int> final = await general
.Add<FirstCommand, string>(x => x.Execute("here we are!"))
.Execute<SecondCommand, int>(x => x.Execute("second!"));
final.Ok.Should().BeTrue();
//final.Data.Should().BeInt();
}
}
public abstract class CommandContext
{
public Type CommandType { get; set; }
public Type ResponseType { get; set; }
}
public class CommandContext<T, TT> : CommandContext
{
public Expression<Func<T, Task<Response<TT>>>> Expression { get; set; }
}
public class General
{
private readonly Dictionary<Type, CommandContext> _commandMap = new Dictionary<Type, CommandContext>();
public General Add<T, TT>(Expression<Func<T, Task<Response<TT>>>> input)
{
if (_commandMap.ContainsKey(typeof(T)))
{
throw new Exception("Command already exists.");
}
_commandMap.Add(typeof(T), new CommandContext<T, TT>
{
CommandType = typeof(T),
ResponseType = typeof(TT),
Expression = input,
});
return this;
}
public async Task<Response<TT>> Execute<T, TT>(Expression<Func<T, Task<Response<TT>>>> input)
{
this.Add(input);
//var item = input.ReturnType;
await Task.FromResult(0);
var response = new Response<TT>()
{
Data = default(TT)
};
foreach (var item in _commandMap)
{
var context = item.Value;
//var command = Activator.CreateInstance(context.CommandType);
//var call = input.Compile();
//await call.Invoke(command);
//var handlerType = typeof(Response<>);
//Type[] typeArgs = { command.Type.GenericTypeArguments[1].GenericTypeArguments[0] };
//var constructed = handlerType.MakeGenericType(typeArgs);
//var handler = Activator.CreateInstance(constructed);
//var c = Activator.CreateInstance<ICommand>(item.Key);
// var method = command.
// var handler = Activator.CreateInstance(item.Key);
// var call = command.Compile();
// await call.Invoke(handler);
//}
var command = getCommandFromContext(context.Expression);
var commandResult = await command.Execute(context.Expression.Paramaters);
if (commandResult.Ok == false)
{
response.Message = commandResult.Message;
break;
}
}
return response;
}
}
public class FirstCommand : ICommand<string, string>
{
public async Task<Response<string>> Execute(string input)
{
await Task.Run(() => Console.Write(input));
return new Response<string>()
{
Data = "first!"
};
}
}
public class SecondCommand : ICommand<int, string>
{
public async Task<Response<int>> Execute(string input)
{
await Task.Run(() => Console.Write(input));
return new Response<int>()
{
Data = 123
};
}
}
public interface ICommand<T, in TT>
{
new Task<Response<T>> Execute(TT input);
}
public class Response<T>
{
public string Message { get; set; }
public bool Ok { get; set; }
public T Data { get; set; }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment