Advertisement
simonradev

CommandActivator

Dec 2nd, 2017
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.32 KB | None | 0 0
  1. namespace BusTicketSystem.CommandDispatcher
  2. {
  3.     using System;
  4.     using System.Collections.Generic;
  5.     using System.Linq.Expressions;
  6.     using System.Reflection;
  7.     using BusTicketSystem.CommandDispatcher.Contracts;
  8.     using BusTicketSystem.Commands.Contracts;
  9.     using Microsoft.Extensions.DependencyInjection;
  10.  
  11.     public class CommandActivator : ICommandActivator
  12.     {
  13.         private static IDictionary<string, Func<IServiceProvider, ICommand>> CommandCache =
  14.                 new Dictionary<string, Func<IServiceProvider, ICommand>>();
  15.         private static readonly Type TypeOfServiceProvider = typeof(IServiceProvider);
  16.         private static readonly Type TypeContainingGetServiceMethod = typeof(ServiceProviderServiceExtensions);
  17.         private static readonly string GetServiceMethodName = nameof(IServiceProvider.GetService);
  18.  
  19.         private ICommandConventions commandConventions;
  20.         private IServiceProvider serviceProvider;
  21.  
  22.         public CommandActivator(ICommandConventions commandConventions,
  23.                                 IServiceProvider serviceProvider)
  24.         {
  25.             this.CommandConventions = commandConventions;
  26.             this.serviceProvider = serviceProvider;
  27.         }
  28.  
  29.         private ICommandConventions CommandConventions
  30.         {
  31.             get
  32.             {
  33.                 return this.commandConventions;
  34.             }
  35.  
  36.             set
  37.             {
  38.                 this.commandConventions = value.CheckNull();
  39.             }
  40.         }
  41.  
  42.         private IServiceProvider ServiceProvider
  43.         {
  44.             get
  45.             {
  46.                 return this.serviceProvider;
  47.             }
  48.  
  49.             set
  50.             {
  51.                 this.serviceProvider = value.CheckNull();
  52.             }
  53.         }
  54.        
  55.         private Expression ParseParameter(ParameterInfo parameterInfo,
  56.                                           ParameterExpression serviceVariable)
  57.         {
  58.             Type[] typeArguments = new[] { parameterInfo.ParameterType };
  59.  
  60.             Expression getServiceCall = Expression.Call(TypeContainingGetServiceMethod,
  61.                                                         GetServiceMethodName,
  62.                                                         typeArguments,
  63.                                                         serviceVariable);
  64.  
  65.             return getServiceCall;
  66.         }
  67.  
  68.         private void AddCommandToLocalCache(string commandName)
  69.         {
  70.             Type commandType = this.CommandConventions.GetCommand(commandName);
  71.             ConstructorInfo commandCtor = this.CommandConventions.GetCtor(commandType);
  72.             ParameterInfo[] parameters = commandCtor.GetParameters();
  73.            
  74.             List<Expression> parsedParams = new List<Expression>();
  75.             ParameterExpression serviceVariable = Expression.Parameter(TypeOfServiceProvider);
  76.             this.ParseParameters(parameters, parsedParams, serviceVariable);
  77.  
  78.             NewExpression newCommandExpression = Expression.New(commandCtor, parsedParams);
  79.             Func<IServiceProvider, ICommand> compiledActivator = Expression.Lambda<Func<IServiceProvider, ICommand>>(newCommandExpression,
  80.                                                                                                                      serviceVariable)
  81.                                                                                                                             .Compile();
  82.             CommandCache[commandName] = compiledActivator;
  83.         }
  84.  
  85.         private void ParseParameters(ParameterInfo[] parameters, List<Expression> parsedParams, ParameterExpression serviceVariable)
  86.         {
  87.             foreach (ParameterInfo paramInfo in parameters)
  88.             {
  89.                 Expression parsedParameter = this.ParseParameter(paramInfo, serviceVariable);
  90.  
  91.                 parsedParams.Add(parsedParameter);
  92.             }
  93.         }
  94.  
  95.         public ICommand Activate(string commandName)
  96.         {
  97.             if (!CommandCache.ContainsKey(commandName))
  98.             {
  99.                 this.AddCommandToLocalCache(commandName);
  100.             }
  101.  
  102.             Func<IServiceProvider, ICommand> activatorFunc = CommandCache[commandName];
  103.             ICommand activatedCommand = activatorFunc(this.ServiceProvider);
  104.  
  105.             return activatedCommand;
  106.         }
  107.     }
  108. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement