Ejemplo n.º 1
0
        /// <summary>
        /// Loads customer assembly, type, and method.
        /// After this call returns without errors, it is possible to invoke
        /// the customer method through the Invoke method.
        /// </summary>
        public void Init(Action <string> customerLoggingAction)
        {
            Assembly customerAssembly = null;

            try
            {
                _logger.LogDebug($"UCL : Parsing handler string '{_handlerString}'");
                _handler = new HandlerInfo(_handlerString);

                // Set the logging action private field on the Amazon.Lambda.Core.LambdaLogger type which is part of the
                // public Amazon.Lambda.Core package when it is loaded.
                AppDomain.CurrentDomain.AssemblyLoad += (sender, args) =>
                {
                    _logger.LogInformation($"UCL : Loaded assembly {args.LoadedAssembly.FullName} into default ALC.");
                    if (!_customerLoggerSetUpComplete && string.Equals(LambdaCoreAssemblyName, args.LoadedAssembly.GetName().Name, StringComparison.Ordinal))
                    {
                        _logger.LogDebug(
                            $"UCL : Load context loading '{LambdaCoreAssemblyName}', attempting to set {Types.LambdaLoggerTypeName}.{LambdaLoggingActionFieldName} to logging action.");
                        SetCustomerLoggerLogAction(args.LoadedAssembly, customerLoggingAction, _logger);
                        _customerLoggerSetUpComplete = true;
                    }
                };

                _logger.LogDebug($"UCL : Attempting to load assembly '{_handler.AssemblyName}'");
                customerAssembly = AssemblyLoadContext.Default.LoadFromAssemblyName(_handler.AssemblyName);
            }
            catch (FileNotFoundException fex)
            {
                _logger.LogError(fex, "An error occured on UCL Init");
                throw LambdaExceptions.ValidationException(Errors.UserCodeLoader.CouldNotFindHandlerAssembly, fex.FileName);
            }
            catch (LambdaValidationException validationException)
            {
                _logger.LogError(validationException, "An error occured on UCL Init");
                throw;
            }
            catch (Exception exception)
            {
                _logger.LogError(exception, "An error occured on UCL Init");
                throw LambdaExceptions.ValidationException(Errors.UserCodeLoader.UnableToLoadAssembly, _handler.AssemblyName);
            }

            _logger.LogDebug($"UCL : Attempting to load type '{_handler.TypeName}'");
            var customerType = customerAssembly.GetType(_handler.TypeName);

            if (customerType == null)
            {
                throw LambdaExceptions.ValidationException(Errors.UserCodeLoader.UnableToLoadType, _handler.TypeName, _handler.AssemblyName);
            }

            _logger.LogDebug($"UCL : Attempting to find method '{_handler.MethodName}' in type '{_handler.TypeName}'");
            CustomerMethodInfo = FindCustomerMethod(customerType);
            _logger.LogDebug($"UCL : Located method '{CustomerMethodInfo}'");

            _logger.LogDebug($"UCL : Validating method '{CustomerMethodInfo}'");
            UserCodeValidator.ValidateCustomerMethod(CustomerMethodInfo);

            var customerObject = GetCustomerObject(customerType);

            var customerSerializerInstance = GetSerializerObject(customerAssembly);

            _logger.LogDebug($"UCL : Constructing invoke delegate");

            var isPreJit = UserCodeInit.IsCallPreJit();
            var builder  = new InvokeDelegateBuilder(_logger, _handler, CustomerMethodInfo);

            _invokeDelegate = builder.ConstructInvokeDelegate(customerObject, customerSerializerInstance, isPreJit);
            if (isPreJit)
            {
                _logger.LogInformation("PreJit: PrepareDelegate");
                RuntimeHelpers.PrepareDelegate(_invokeDelegate);
            }
        }