Exemple #1
0
        /// <summary>
        /// Initializes a new interpreter and discovers methods marked
        /// with <see cref="CommandHandlerAttribute"/> attribute.
        /// </summary>
        protected CommandInterpreter()
        {
            var interpreters = new Dictionary <int, CommandHandler>();
            var formatters   = new Dictionary <Type, FormatterInfo>();
            const BindingFlags publicInstanceMethod = BindingFlags.Public | BindingFlags.Instance;

            foreach (var method in GetType().GetMethods(publicInstanceMethod))
            {
                var handlerAttr = method.GetCustomAttribute <CommandHandlerAttribute>();
                if (handlerAttr is not null && method.ReturnType == typeof(ValueTask))
                {
                    var parameters = method.GetParameterTypes();
                    if (GetLength(parameters) != 2 || !parameters[0].IsValueType || parameters[1] != typeof(CancellationToken))
                    {
                        continue;
                    }
                    var commandType = parameters[0];
                    var commandAttr = commandType.GetCustomAttribute <CommandAttribute>();
                    if (commandAttr is null || commandAttr.Formatter is null)
                    {
                        continue;
                    }
                    var formatter = new FormatterInfo(commandAttr);
                    if (formatter.IsEmpty)
                    {
                        continue;
                    }
                    var interpreter = Delegate.CreateDelegate(typeof(Func <, ,>).MakeGenericType(commandType, typeof(CancellationToken), typeof(ValueTask)), method.IsStatic ? null : this, method);
                    interpreters.Add(commandAttr.Id, Cast <CommandHandler>(Activator.CreateInstance(typeof(CommandHandler <>).MakeGenericType(commandType), formatter, interpreter)));
                    formatters.Add(commandType, formatter);
                }
            }

            this.interpreters = CreateRegistry(interpreters);
            interpreters.Clear();

            formatters.TrimExcess();
            this.formatters = formatters;
        }