private static ObjectActivator DictionaryActivator(Type expectedType)
        {
            var genericArgs = expectedType.GetGenericArguments();

            if (genericArgs.Length != 2)
            {
                throw new DeserializationException(
                          $"Unexpected number of Dictionary generic arguments: {genericArgs.Length}");
            }
            ConstructorInfo constructor;

            if (expectedType.IsInterface)
            {
                var dictType = typeof(Dictionary <,>).MakeGenericType(genericArgs);
                ReflectionUtil.CheckType(expectedType, dictType);
                constructor = dictType.GetConstructor(new[] { typeof(int) });
            }
            else
            {
                ReflectionUtil.CheckType(typeof(IDictionary), expectedType);
                constructor = expectedType.GetConstructor(Type.EmptyTypes);
                if (constructor == null)
                {
                    throw new DeserializationException($"Unable to find default constructor for {expectedType}");
                }
            }
            var activator = ReflectionUtil.CreateActivator(constructor);

            return(activator);
        }
Beispiel #2
0
        private static ObjectActivator ListActivator(Type expectedType)
        {
            var genericArgs = expectedType.GetGenericArguments();
            var argType     = genericArgs.Length switch
            {
                0 => typeof(object),
                1 => genericArgs[0],
                _ => throw new DeserializationException(
                          $"Unexpected number of generic arguments for list: {genericArgs.Length}"),
            };
            ConstructorInfo constructor;
            var             interfaceType = typeof(ICollection <>).MakeGenericType(argType);
            var             listType      = typeof(List <>).MakeGenericType(argType);

            if (expectedType.IsAssignableFrom(listType))
            {
                constructor = listType.GetConstructor(new[] { typeof(int) });
            }
            else
            {
                ReflectionUtil.CheckType(interfaceType, expectedType);
                constructor = expectedType.GetConstructor(Type.EmptyTypes);
                if (constructor == null)
                {
                    throw new DeserializationException($"Unable to find default constructor for {expectedType}");
                }
            }
            var activator = ReflectionUtil.CreateActivator(constructor);

            return(activator);
        }
        private static TypeActivator ClassActivator(Type expectedType)
        {
            var constructors =
                expectedType.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
                .Where(c => c.IsDefined(typeof(ConstructorAttribute), true))
                .ToList();

            if (constructors.Count == 0)
            {
                throw new DeserializationException(
                          $"No constructors found for {expectedType} found with MaxMind.Db.Constructor attribute");
            }
            if (constructors.Count > 1)
            {
                throw new DeserializationException(
                          $"More than one constructor found for {expectedType} found with MaxMind.Db/Constructor attribute");
            }

            var constructor    = constructors[0];
            var parameters     = constructor.GetParameters();
            var paramNameTypes = new Dictionary <byte[], ParameterInfo>(new ByteArrayEqualityComparer());
            var injectables    = new Dictionary <string, ParameterInfo>();
            var networkParams  = new List <ParameterInfo>();
            var alwaysCreated  = new List <ParameterInfo>();

            foreach (var param in parameters)
            {
                var injectableAttribute = param.GetCustomAttributes <InjectAttribute>().FirstOrDefault();
                if (injectableAttribute != null)
                {
                    injectables.Add(injectableAttribute.ParameterName, param);
                }
                var networkAttribute = param.GetCustomAttributes <NetworkAttribute>().FirstOrDefault();
                if (networkAttribute != null)
                {
                    networkParams.Add(param);
                }
                var    paramAttribute = param.GetCustomAttributes <ParameterAttribute>().FirstOrDefault();
                string name;
                if (paramAttribute != null)
                {
                    name = paramAttribute.ParameterName;
                    if (paramAttribute.AlwaysCreate)
                    {
                        alwaysCreated.Add(param);
                    }
                }
                else
                {
                    name = param.Name;
                }
                paramNameTypes.Add(Encoding.UTF8.GetBytes(name), param);
            }
            var activator      = ReflectionUtil.CreateActivator(constructor);
            var clsConstructor = new TypeActivator(activator, paramNameTypes, injectables, networkParams, alwaysCreated);

            return(clsConstructor);
        }