/// <summary> /// Creates a dynamic method that gets the IDs from the object. /// </summary> /// <typeparam name="TObject">The type of object.</typeparam> /// <typeparam name="TValue">The type of the value.</typeparam> /// <returns>A method that can extract the IDs.</returns> public Func <TObject, TValue> CreateGetMethod <TObject, TValue>() { if (_propInfo.Count == 1) { return(_propInfo.First().CreateGetMethod <TObject, TValue>()); } else { var dm = new DynamicMethod( String.Format(CultureInfo.InvariantCulture, "Get-{0}-{1}-{2}", typeof(TObject).FullName, "IDs", Guid.NewGuid()), MemberType, new Type[] { typeof(TObject) }, true); var il = dm.GetILGenerator(); // get all of the values foreach (var p in _propInfo) { il.Emit(OpCodes.Ldarg_0); p.EmitGetValue(il); } var createTupleMethod = typeof(Tuple).GetMethods(BindingFlags.Static | BindingFlags.Public) .Single(m => m.Name == "Create" && m.GetGenericArguments().Length == _propInfo.Count) .MakeGenericMethod(MemberType.GetGenericArguments()); // create the tuple il.Emit(OpCodes.Call, createTupleMethod); il.Emit(OpCodes.Ret); return((Func <TObject, TValue>)dm.CreateDelegate(typeof(Func <TObject, TValue>))); } }
public DictionaryMember(string name, Type type) : base(name, type) { var types = MemberType.GetGenericArguments(); _keyType = types[0]; _valueType = types[1]; TypeName = "Dict<" + _keyType.Name + ',' + _valueType.Name + ">"; }
public Relationship(MemberInfo member, IRelationshipInfo relationshipInfo) { Member = member; MemberType = ReflectionHelper.GetMemberType(member); // Try to determine the RelationshipType if (relationshipInfo.RelationType == RelationshipTypes.AutoDetect) { if (typeof(ICollection).IsAssignableFrom(MemberType)) { relationshipInfo.RelationType = RelationshipTypes.Many; } else { relationshipInfo.RelationType = RelationshipTypes.One; } } // Try to determine the EntityType if (relationshipInfo.EntityType == null) { if (relationshipInfo.RelationType == RelationshipTypes.Many) { if (MemberType.IsGenericType) { // Assume a Collection<T> or List<T> and return T relationshipInfo.EntityType = MemberType.GetGenericArguments()[0]; } else { throw new ArgumentException(string.Format( "The DataMapper could not determine the RelationshipAttribute EntityType for {0}.", MemberType.Name)); } } else { relationshipInfo.EntityType = MemberType; } } RelationshipInfo = relationshipInfo; Setter = MapRepository.Instance.ReflectionStrategy.BuildSetter(member.DeclaringType, member.Name); }
/// <summary> /// Initialize the PropertyInfo of the result property. /// </summary> /// <param name="resultClass"></param> /// <param name="configScope"></param> public void Initialize(ConfigurationScope configScope, Type resultClass) { if (_propertyName.Length > 0 && _propertyName != "value" && !typeof(IDictionary).IsAssignableFrom(resultClass)) { if (!_isComplexMemberName) { _setAccessor = configScope.DataExchangeFactory.AccessorFactory.SetAccessorFactory.CreateSetAccessor(resultClass, _propertyName); } else // complex member name FavouriteLineItem.Id { MemberInfo propertyInfo = ObjectProbe.GetMemberInfoForSetter(resultClass, _propertyName); string memberName = _propertyName.Substring(_propertyName.LastIndexOf('.') + 1); _setAccessor = configScope.DataExchangeFactory.AccessorFactory.SetAccessorFactory.CreateSetAccessor(propertyInfo.ReflectedType, memberName); } //#if dotnet2 _isGenericIList = TypeUtils.IsImplementGenericIListInterface(MemberType); //#endif _isIList = typeof(IList).IsAssignableFrom(MemberType); // set the list factory //#if dotnet2 if (_isGenericIList) { if (MemberType.IsArray) { _listFactory = _arrayListFactory; } else { Type[] typeArgs = MemberType.GetGenericArguments(); if (typeArgs.Length == 0)// Custom collection which derive from List<T> { _listFactory = configScope.DataExchangeFactory.ObjectFactory.CreateFactory(MemberType, Type.EmptyTypes); } else { Type genericIList = typeof(IList <>); Type interfaceListType = genericIList.MakeGenericType(typeArgs); Type genericList = typeof(List <>); Type listType = genericList.MakeGenericType(typeArgs); if ((interfaceListType == MemberType) || (listType == MemberType)) { Type constructedType = genericList.MakeGenericType(typeArgs); _listFactory = configScope.DataExchangeFactory.ObjectFactory.CreateFactory( constructedType, Type.EmptyTypes); } else // Custom collection which derive from List<T> { _listFactory = configScope.DataExchangeFactory.ObjectFactory.CreateFactory(MemberType, Type.EmptyTypes); } } } } else //#endif if (_isIList) { if (MemberType.IsArray) { _listFactory = _arrayListFactory; } else { if (MemberType == typeof(IList)) { _listFactory = _arrayListFactory; } else // custom collection { _listFactory = configScope.DataExchangeFactory.ObjectFactory.CreateFactory(MemberType, Type.EmptyTypes); } } } } if (CallBackName != null && CallBackName.Length > 0) { configScope.ErrorContext.MoreInfo = "Result property '" + _propertyName + "' check the typeHandler attribute '" + CallBackName + "' (must be a ITypeHandlerCallback implementation)."; try { Type type = configScope.SqlMapper.TypeHandlerFactory.GetType(CallBackName); ITypeHandlerCallback typeHandlerCallback = (ITypeHandlerCallback)Activator.CreateInstance(type); _typeHandler = new CustomTypeHandler(typeHandlerCallback); } catch (Exception e) { throw new ConfigurationException("Error occurred during custom type handler configuration. Cause: " + e.Message, e); } } else { configScope.ErrorContext.MoreInfo = "Result property '" + _propertyName + "' set the typeHandler attribute."; _typeHandler = configScope.ResolveTypeHandler(resultClass, _propertyName, _clrType, _dbType, true); } if (IsLazyLoad) { _lazyFactory = new LazyFactoryBuilder().GetLazyFactory(_setAccessor.MemberType); } }
public ListMember(string name, Type type) : base(name, type) { _elementType = MemberType.GetGenericArguments()[0]; TypeName = "List<" + _elementType.Name + ">"; }
internal bool ResolveMapTypes(out Type dictionaryType, out Type keyType, out Type valueType) { dictionaryType = keyType = valueType = null; try { #if COREFX || PROFILE259 var info = MemberType.GetTypeInfo(); #else var info = MemberType; #endif if (ImmutableCollectionDecorator.IdentifyImmutable(MemberType, out _, out _, out _, out _, out _, out _)) { return(false); } if (info.IsInterface && info.IsGenericType && info.GetGenericTypeDefinition() == typeof(IDictionary <,>)) { #if PROFILE259 var typeArgs = MemberType.GetGenericTypeDefinition().GenericTypeArguments; #else var typeArgs = MemberType.GetGenericArguments(); #endif if (IsValidMapKeyType(typeArgs[0])) { keyType = typeArgs[0]; valueType = typeArgs[1]; dictionaryType = MemberType; } return(false); } #if PROFILE259 foreach (var iType in MemberType.GetTypeInfo().ImplementedInterfaces) #else foreach (var iType in MemberType.GetInterfaces()) #endif { #if COREFX || PROFILE259 info = iType.GetTypeInfo(); #else info = iType; #endif if (info.IsGenericType && info.GetGenericTypeDefinition() == typeof(IDictionary <,>)) { if (dictionaryType != null) { throw new InvalidOperationException("Multiple dictionary interfaces implemented by type: " + MemberType.FullName); } #if PROFILE259 var typeArgs = iType.GetGenericTypeDefinition().GenericTypeArguments; #else var typeArgs = iType.GetGenericArguments(); #endif if (IsValidMapKeyType(typeArgs[0])) { keyType = typeArgs[0]; valueType = typeArgs[1]; dictionaryType = MemberType; } } } if (dictionaryType == null) { return(false); } // (note we checked the key type already) // not a map if value is repeated Type itemType = null, defaultType = null; model.ResolveListTypes(valueType, ref itemType, ref defaultType); if (itemType != null) { return(false); } return(dictionaryType != null); } catch { // if it isn't a good fit; don't use "map" return(false); } }
public Relationship(MemberInfo member, IRelationshipInfo relationshipInfo) { Member = member; MemberType = ReflectionHelper.GetMemberType(member); // Try to determine the RelationshipType if (relationshipInfo.RelationType == RelationshipTypes.AutoDetect) { if (member.MemberType == MemberTypes.Field && MemberType == typeof(object)) { // Handles dynamic member fields that are lazy loaded var prop = DataHelper.FindPropertyForBackingField(member.ReflectedType, member); if (prop != null) { if (typeof(System.Collections.IEnumerable).IsAssignableFrom(prop.ReturnType)) { relationshipInfo.RelationType = RelationshipTypes.Many; } else { relationshipInfo.RelationType = RelationshipTypes.One; } } } else { if (typeof(System.Collections.IEnumerable).IsAssignableFrom(MemberType)) { relationshipInfo.RelationType = RelationshipTypes.Many; } else { relationshipInfo.RelationType = RelationshipTypes.One; } } } // Try to determine the EntityType if (relationshipInfo.EntityType == null) { if (relationshipInfo.RelationType == RelationshipTypes.Many) { if (MemberType.IsGenericType) { // Assume a Collection<T> or List<T> and return T relationshipInfo.EntityType = MemberType.GetGenericArguments()[0]; } else if (MemberType == typeof(object)) { relationshipInfo.EntityType = typeof(object); } else { throw new ArgumentException(string.Format( "The DataMapper could not determine the RelationshipAttribute EntityType for {0}.", MemberType.Name)); } } else { relationshipInfo.EntityType = MemberType; } } RelationshipInfo = relationshipInfo; Setter = MapRepository.Instance.ReflectionStrategy.BuildSetter(member.DeclaringType, member.Name); }
/// <summary> /// Initializes a new instance of the <see cref="ResultProperty"/> class. /// </summary> /// <param name="propertyName">Name of the property.</param> /// <param name="columnName">Name of the column.</param> /// <param name="columnIndex">Index of the column.</param> /// <param name="clrType">Type of the CLR.</param> /// <param name="callBackName">Name of the call back.</param> /// <param name="dbType">Type of the db.</param> /// <param name="isLazyLoad">if set to <c>true</c> [is lazy load].</param> /// <param name="nestedResultMapName">Name of the nested result map.</param> /// <param name="nullValue">The null value.</param> /// <param name="select">The select.</param> /// <param name="resultClass">The result class.</param> /// <param name="dataExchangeFactory">The data exchange factory.</param> /// <param name="typeHandler">The type handler.</param> public ResultProperty( string propertyName, string columnName, int columnIndex, string clrType, string callBackName, string dbType, bool isLazyLoad, string nestedResultMapName, string nullValue, string select, Type resultClass, DataExchangeFactory dataExchangeFactory, ITypeHandler typeHandler ) { Contract.Require.That(propertyName, Is.Not.Null & Is.Not.Empty).When("retrieving argument propertyName in ResultProperty constructor"); this.propertyName = propertyName; this.columnName = columnName; this.callBackName = callBackName; this.dbType = dbType; this.clrType = clrType; this.select = select; this.nestedResultMapName = nestedResultMapName; this.isLazyLoad = isLazyLoad; this.nullValue = nullValue; this.columnIndex = columnIndex; this.typeHandler = typeHandler; #region isComplexMemberName if (propertyName.IndexOf('.') < 0) { isComplexMemberName = false; } else // complex member name FavouriteLineItem.Id { isComplexMemberName = true; } #endregion if (propertyName.Length > 0 && propertyName != "value" && !typeof(IDictionary).IsAssignableFrom(resultClass) && !typeof(DataRow).IsAssignableFrom(resultClass)) { #region SetAccessor if (!isComplexMemberName) { setAccessor = dataExchangeFactory.AccessorFactory.SetAccessorFactory.CreateSetAccessor(resultClass, propertyName); } else // complex member name FavouriteLineItem.Id { MemberInfo propertyInfo = ObjectProbe.GetMemberInfoForSetter(resultClass, propertyName); string memberName = propertyName.Substring(propertyName.LastIndexOf('.') + 1); setAccessor = dataExchangeFactory.AccessorFactory.SetAccessorFactory.CreateSetAccessor(propertyInfo.ReflectedType, memberName); } #endregion isGenericIList = TypeUtils.IsImplementGenericIListInterface(MemberType); isIList = typeof(IList).IsAssignableFrom(MemberType); #region Set the list factory if (isGenericIList) { if (MemberType.IsArray) { listFactory = arrayListFactory; } else { Type[] typeArgs = MemberType.GetGenericArguments(); if (typeArgs.Length == 0)// Custom collection which derive from List<T> { listFactory = dataExchangeFactory.ObjectFactory.CreateFactory(MemberType, Type.EmptyTypes); } else { Type genericIList = typeof(IList <>); Type interfaceListType = genericIList.MakeGenericType(typeArgs); Type genericList = typeof(List <>); Type listType = genericList.MakeGenericType(typeArgs); if ((interfaceListType == MemberType) || (listType == MemberType)) { Type constructedType = genericList.MakeGenericType(typeArgs); listFactory = dataExchangeFactory.ObjectFactory.CreateFactory( constructedType, Type.EmptyTypes); } else // Custom collection which derive from List<T> { listFactory = dataExchangeFactory.ObjectFactory.CreateFactory(MemberType, Type.EmptyTypes); } } } } else if (isIList) { if (MemberType.IsArray) { listFactory = arrayListFactory; } else { if (MemberType == typeof(IList)) { listFactory = arrayListFactory; } else // custom collection { listFactory = dataExchangeFactory.ObjectFactory.CreateFactory(MemberType, Type.EmptyTypes); } } } #endregion } #region TypeHandler if (!string.IsNullOrEmpty(CallBackName)) { try { Type type = dataExchangeFactory.TypeHandlerFactory.GetType(CallBackName); ITypeHandlerCallback typeHandlerCallback = (ITypeHandlerCallback)Activator.CreateInstance(type); this.typeHandler = new CustomTypeHandler(typeHandlerCallback); } catch (Exception e) { throw new ConfigurationException("Error occurred during custom type handler configuration. Cause: " + e.Message, e); } } else { if (typeHandler == null) { //configScope.ErrorContext.MoreInfo = "Result property '" + propertyName + "' set the typeHandler attribute."; this.typeHandler = dataExchangeFactory.TypeHandlerFactory.ResolveTypeHandler(resultClass, propertyName, clrType, dbType, true); } } #endregion #region LazyLoad if (IsLazyLoad) { lazyFactory = new LazyFactoryBuilder().GetLazyFactory(setAccessor.MemberType); } #endregion if (!GetType().IsSubclassOf(typeof(ResultProperty))) { propertyStrategy = PropertyStrategyFactory.Get(this); } }