private static Type GetIDictionaryType(MapTypeContext context) { return(context.TargetType.GetInterfaces() .Where(i => i.IsGenericType) .FirstOrDefault(i => i.GetGenericTypeDefinition() == typeof(IDictionary <,>) && i.GenericTypeArguments[0] == typeof(string)) ?? throw MapCompilerException.InvalidDictionaryTargetType(context.TargetType)); }
public ScalarCompiler(IEnumerable <IScalarMapCompiler> scalarCompilers) { _scalarCompilers = scalarCompilers.ToList(); if (_scalarCompilers.Count == 0) { throw MapCompilerException.NoScalarMapCompilers(); } }
private ConcreteCollectionInfo GetTypeInfo(MapTypeContext context) { var targetType = context.TargetType; var typeSettings = context.Settings.GetTypeSettings(targetType); if (typeSettings.BaseType != typeof(object)) { targetType = typeSettings.GetDefault().Type; } // We absolutely need a constructor here, there's no way around it. The user has asked // for a specific concrete type, we can either return that type or the configured // subclass, but we can't default to something else with a parameterless constructor var constructor = targetType.GetConstructor(Type.EmptyTypes); if (constructor == null) { throw MapCompilerException.InvalidCollectionType(targetType); } // Same with .Add(). The type absolutely must have a .Add(T) method variant or we // cannot proceed var addMethods = targetType .GetMethods(BindingFlags.Public | BindingFlags.Instance) .Where(m => m.Name == AddMethodName && m.GetParameters().Length == 1) .ToList(); if (addMethods.Count == 0) { throw MapCompilerException.InvalidCollectionType(targetType); } // Find all IEnumerable<T> interfaces. For each one we're going to look for a matching // .Add(T) method. If we find a match, that's what we're going with. var iEnumerableOfTTypes = targetType .GetInterfaces() .Where(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IEnumerable <>)) .ToDictionary(t => t.GetGenericArguments()[0]); if (iEnumerableOfTTypes.Count > 0) { var bestAddMethod = addMethods.FirstOrDefault(m => iEnumerableOfTTypes.ContainsKey(m.GetParameters()[0].ParameterType)); if (bestAddMethod != null) { var bestAddElementType = bestAddMethod.GetParameters()[0].ParameterType; return(new ConcreteCollectionInfo(targetType, bestAddElementType, constructor, bestAddMethod)); } } // At this point we know the collection must be IEnumerable because of precondition // checks. So we'll just use any available Add method var addMethod = addMethods.FirstOrDefault(); var elementType = addMethod.GetParameters()[0].ParameterType; return(new ConcreteCollectionInfo(targetType, elementType, constructor, addMethod)); }
private static ConstructorInfo GetDictionaryConstructor(Type targetType) { return(targetType.GetConstructor(Type.EmptyTypes) ?? throw MapCompilerException.InvalidDictionaryTargetType(targetType)); }
private static MethodInfo GetIDictionaryAddMethod(Type targetType, Type idictType) { return(idictType.GetMethod(nameof(IDictionary <string, object> .Add)) ?? throw MapCompilerException.InvalidDictionaryTargetType(targetType)); }