Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- namespace BusTicketSystem.CommandDispatcher
- {
- using System;
- using System.Collections.Generic;
- using System.Linq.Expressions;
- using System.Reflection;
- using BusTicketSystem.CommandDispatcher.Contracts;
- using BusTicketSystem.Commands.Contracts;
- using Microsoft.Extensions.DependencyInjection;
- public class CommandActivator : ICommandActivator
- {
- private static IDictionary<string, Func<IServiceProvider, ICommand>> CommandCache =
- new Dictionary<string, Func<IServiceProvider, ICommand>>();
- private static readonly Type TypeOfServiceProvider = typeof(IServiceProvider);
- private static readonly Type TypeContainingGetServiceMethod = typeof(ServiceProviderServiceExtensions);
- private static readonly string GetServiceMethodName = nameof(IServiceProvider.GetService);
- private ICommandConventions commandConventions;
- private IServiceProvider serviceProvider;
- public CommandActivator(ICommandConventions commandConventions,
- IServiceProvider serviceProvider)
- {
- this.CommandConventions = commandConventions;
- this.serviceProvider = serviceProvider;
- }
- private ICommandConventions CommandConventions
- {
- get
- {
- return this.commandConventions;
- }
- set
- {
- this.commandConventions = value.CheckNull();
- }
- }
- private IServiceProvider ServiceProvider
- {
- get
- {
- return this.serviceProvider;
- }
- set
- {
- this.serviceProvider = value.CheckNull();
- }
- }
- private Expression ParseParameter(ParameterInfo parameterInfo,
- ParameterExpression serviceVariable)
- {
- Type[] typeArguments = new[] { parameterInfo.ParameterType };
- Expression getServiceCall = Expression.Call(TypeContainingGetServiceMethod,
- GetServiceMethodName,
- typeArguments,
- serviceVariable);
- return getServiceCall;
- }
- private void AddCommandToLocalCache(string commandName)
- {
- Type commandType = this.CommandConventions.GetCommand(commandName);
- ConstructorInfo commandCtor = this.CommandConventions.GetCtor(commandType);
- ParameterInfo[] parameters = commandCtor.GetParameters();
- List<Expression> parsedParams = new List<Expression>();
- ParameterExpression serviceVariable = Expression.Parameter(TypeOfServiceProvider);
- this.ParseParameters(parameters, parsedParams, serviceVariable);
- NewExpression newCommandExpression = Expression.New(commandCtor, parsedParams);
- Func<IServiceProvider, ICommand> compiledActivator = Expression.Lambda<Func<IServiceProvider, ICommand>>(newCommandExpression,
- serviceVariable)
- .Compile();
- CommandCache[commandName] = compiledActivator;
- }
- private void ParseParameters(ParameterInfo[] parameters, List<Expression> parsedParams, ParameterExpression serviceVariable)
- {
- foreach (ParameterInfo paramInfo in parameters)
- {
- Expression parsedParameter = this.ParseParameter(paramInfo, serviceVariable);
- parsedParams.Add(parsedParameter);
- }
- }
- public ICommand Activate(string commandName)
- {
- if (!CommandCache.ContainsKey(commandName))
- {
- this.AddCommandToLocalCache(commandName);
- }
- Func<IServiceProvider, ICommand> activatorFunc = CommandCache[commandName];
- ICommand activatedCommand = activatorFunc(this.ServiceProvider);
- return activatedCommand;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement