Aws lambda ASP.NET Core 2.1和#x27;在AWS lambda中部署时无法工作

Aws lambda ASP.NET Core 2.1和#x27;在AWS lambda中部署时无法工作,aws-lambda,asp.net-core-2.1,system.reflection,Aws Lambda,Asp.net Core 2.1,System.reflection,我有一个库,其中包含以下用于依赖项注入的代码。这将加载以Handler结尾的所有实现类并注册它们 public static class HandlerRegistrationExtension { private static IDictionary<Type, Type> _decoratorsAttributes; public static void AddHandlers(this IServiceCollection servic

我有一个库,其中包含以下用于依赖项注入的代码。这将加载以
Handler
结尾的所有实现类并注册它们

public static class HandlerRegistrationExtension
    {
        private static IDictionary<Type, Type> _decoratorsAttributes;

        public static void AddHandlers(this IServiceCollection services, IDictionary<Type, Type> decoratorsAttributes)
        {
            _decoratorsAttributes = decoratorsAttributes ?? new Dictionary<Type, Type>();

            List<Type> allAssembliesTypes = Assembly
                                    .GetEntryAssembly()
                                    .GetReferencedAssemblies()
                                    .Select(Assembly.Load)
                                    .SelectMany(a => a.GetTypes())
                                    .ToList();

            List<Type> handlerTypes = allAssembliesTypes
                                        .Where(x => x.GetInterfaces().Any(y => IsHandlerInterface(y)))
                                        .Where(x => x.Name.EndsWith("Handler", StringComparison.Ordinal))
                                        .ToList();

            foreach (Type type in handlerTypes)
            {
                AddHandler(services, type);
            }
        }

        private static void AddHandler(IServiceCollection services, Type type)
        {
            object[] attributes = type.GetCustomAttributes(false);

            List<Type> pipeline = attributes
                                    .Select(x => ToDecorator(x))
                                    .Concat(new[] { type })
                                    .Reverse()
                                    .ToList();

            Type interfaceType = type.GetInterfaces().Single(y => IsHandlerInterface(y));
            Func<IServiceProvider, object> factory = BuildPipeline(pipeline, interfaceType);

            services.AddTransient(interfaceType, factory);
        }

        private static Func<IServiceProvider, object> BuildPipeline(List<Type> pipeline, Type interfaceType)
        {
            List<ConstructorInfo> ctors = pipeline
                .Select(x =>
                {
                    Type type = x.IsGenericType ? x.MakeGenericType(interfaceType.GenericTypeArguments) : x;
                    return type.GetConstructors().Single();
                })
                .ToList();

            Func<IServiceProvider, object> func = provider =>
            {
                object current = null;

                foreach (ConstructorInfo ctor in ctors)
                {
                    List<ParameterInfo> parameterInfos = ctor.GetParameters().ToList();

                    object[] parameters = GetParameters(parameterInfos, current, provider);

                    current = ctor.Invoke(parameters);
                }

                return current;
            };

            return func;
        }

        private static object[] GetParameters(List<ParameterInfo> parameterInfos, object current, IServiceProvider provider)
        {
            var result = new object[parameterInfos.Count];

            for (int i = 0; i < parameterInfos.Count; i++)
            {
                result[i] = GetParameter(parameterInfos[i], current, provider);
            }

            return result;
        }

        private static object GetParameter(ParameterInfo parameterInfo, object current, IServiceProvider provider)
        {
            Type parameterType = parameterInfo.ParameterType;

            if (IsHandlerInterface(parameterType))
                return current;

            object service = provider.GetService(parameterType);
            if (service != null)
                return service;

            throw new ArgumentException($"Type {parameterType} not found");
        }

        private static Type ToDecorator(object attribute)
        {
            Type type = attribute.GetType();

            if (_decoratorsAttributes.ContainsKey(type))
            {
                return _decoratorsAttributes[type];
            }

            throw new ArgumentException(attribute.ToString());
        }

        private static bool IsHandlerInterface(Type type)
        {
            if (!type.IsGenericType)
                return false;

            Type typeDefinition = type.GetGenericTypeDefinition();

            return typeDefinition == typeof(ICommandHandler<,>) || typeDefinition == typeof(IQueryHandler<,>);
        }
    }
公共静态类HandlerRegistrationExtension
{
私有静态IDictionary _decorators属性;
公共静态void AddHandlers(此IServiceCollection服务、IDictionary decoratorsAttributes)
{
_decoratorAttributes=decoratorAttributes??新建字典();
列出所有组件类型=组件
.GetEntryAssembly()
.getReferencedAssemblys()
.Select(Assembly.Load)
.SelectMany(a=>a.GetTypes())
.ToList();
列表句柄类型=所有assembliestypes
.Where(x=>x.GetInterfaces().Any(y=>IsHandlerInterface(y)))
.Where(x=>x.Name.EndsWith(“Handler”,StringComparison.Ordinal))
.ToList();
foreach(handlerTypes中的类型)
{
AddHandler(服务,类型);
}
}
私有静态void AddHandler(IServiceCollection服务,类型)
{
object[]attributes=type.GetCustomAttributes(false);
列表管道=属性
.选择(x=>ToDecorator(x))
.Concat(新[]{type})
.Reverse()
.ToList();
Type interfaceType=Type.GetInterfaces().Single(y=>IsHandlerInterface(y));
Func factory=BuildPipeline(管道,接口类型);
服务。AddTransient(接口类型,工厂);
}
私有静态Func BuildPipeline(列表管道,类型interfaceType)
{
列表系数=管道
.选择(x=>
{
Type Type=x.IsGenericType?x.MakeGenericType(interfaceType.GenericTypeArguments):x;
返回类型.GetConstructors().Single();
})
.ToList();
Func Func=提供程序=>
{
对象当前=空;
foreach(构造函数中的构造函数)
{
List ParameterInfo=ctor.GetParameters().ToList();
object[]parameters=GetParameters(ParameterInfo、current、provider);
current=ctor.Invoke(参数);
}
回流;
};
返回函数;
}
私有静态对象[]GetParameters(列出参数信息、当前对象、IServiceProvider提供程序)
{
var结果=新对象[ParameterInfo.Count];
for(int i=0;i
当我在AWS Lambda函数中部署应用程序时,似乎找不到请求处理程序实现的代码

private readonly IServiceProvider _provider;

        public MessagesDispatcher(IServiceProvider provider)
        {
            _provider = provider;
        }

        public async Task<T> DispatchAsync<T>(ICommand<T> command, CancellationToken cancellationToken)
        {
            Type type = typeof(ICommandHandler<,>);
            Type[] typeArgs = { command.GetType(), typeof(T) };
            Type handlerType = type.MakeGenericType(typeArgs);

            dynamic handler = _provider.GetService(handlerType);
            T result = await handler.HandleAsync((dynamic)command, cancellationToken);

            return result;
        }
private readonly-IServiceProvider\u提供程序;
公共消息分发程序(IServiceProvider提供程序)
{
_提供者=提供者;
}
公共异步任务DispatchAsync(ICommand命令,CancellationToken CancellationToken)
{
Type Type=typeof(ICommandHandler);
Type[]typeArgs={command.GetType(),typeof(T)};
类型handlerType=Type.MakeGenericType(类型args);
动态处理程序=_provider.GetService(handlerType);
T result=await handler.HandleAsync((动态)命令,cancellationToken);
返回结果;
}

我想知道在与加载了反射的程序集相关的lambda中部署应用程序会有什么变化,因为在使用
LocalEntryPoint.cs

时,代码可以正常工作。经过一段搜索和尝试/失败过程后,我发现下面的获取程序集并确定二进制文件的类型的方法在AWS中有效Lambda环境。下面是已更改的方法
AddHandlers

public static void AddHandlers(
            this IServiceCollection services, 
            IDictionary<Type, Type> decoratorsAttributes,
            params Assembly[] assemblies) // Added a parameter to pass multiple assemblies
        {
            _decoratorsAttributes = decoratorsAttributes ?? new Dictionary<Type, Type>();

            List<Type> allAssembliesTypes = assemblies // Here we get the types from the assembly
                                                .SelectMany(a => a.GetTypes())
                                                .ToList();

            List<Type> handlerTypes = allAssembliesTypes
                                        .Where(x => x.GetInterfaces().Any(y => IsHandlerInterface(y)))
                                        .Where(x => x.Name.EndsWith("Handler", StringComparison.Ordinal))
                                        .ToList();

            foreach (Type type in handlerTypes)
            {
                AddHandler(services, type);
            }
        }
services.AddHandlers(new Dictionary<Type, Type>
            {
                { typeof(CircuitBreakerCommandDecoratorAttribute), typeof(CircuitBreakerCommandDecorator<,>) },
                { typeof(CircuitBreakerQueryDecoratorAttribute), typeof(CircuitBreakerQueryDecorator<,>) }
            },
            typeof(RegisterUserCommandHandler).GetTypeInfo().Assembly); .. This way the assembly containing the types I am scanning is loaded correctly