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); }
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); }