/// <summary> /// 원본 객체 정보를 대상 객체를 생성하여, 같은 속성명의 값을 매핑합니다. /// </summary> /// <typeparam name="TSource"></typeparam> /// <typeparam name="TTarget">대상 인스턴스 수형</typeparam> /// <param name="source">원본 인스턴스</param> /// <param name="target">대상 인스턴스</param> /// <param name="mapOptions">매핑 시의 옵션</param> /// <param name="propertyExprsToExclude">제외할 속성명</param> /// <returns>매핑된 대상 객체</returns> public static void MapObject <TSource, TTarget>(this TSource source, TTarget target, MapPropertyOptions mapOptions, params Expression <Func <TTarget, object> >[] propertyExprsToExclude) { MapObject(source, target, mapOptions, null, propertyExprsToExclude); }
/// <summary> /// 원본 객체 정보를 대상 객체를 생성하여, 같은 속성명의 값을 매핑하여 반환합니다. /// </summary> /// <typeparam name="TSource"></typeparam> /// <typeparam name="TTarget">대상 인스턴스 수형</typeparam> /// <param name="source">원본 인스턴스</param> /// <param name="targetFactory">대상 인스턴스 생성 팩토리</param> /// <param name="mapOptions">매핑 시의 옵션</param> /// <param name="propertyExprsToExclude">제외할 속성명</param> /// <returns>매핑된 대상 객체</returns> public static TTarget MapObject <TSource, TTarget>(this TSource source, Func <TTarget> targetFactory, MapPropertyOptions mapOptions, params Expression <Func <TTarget, object> >[] propertyExprsToExclude) { return(MapObject(source, targetFactory, mapOptions, null, propertyExprsToExclude)); }
internal DynamicAccessorKey(Type targetType, MapPropertyOptions mapOption) { targetType.ShouldNotBeNull("targetType"); TargetType = targetType; MapOption = mapOption ?? MapPropertyOptions.Default; }
/// <summary> /// 원본 시퀀스를 이용하여 대상 객체를 생성한 후, 속성 값을 매핑하여 반환합니다. /// </summary> /// <typeparam name="TSource"></typeparam> /// <typeparam name="TTarget">대상 인스턴스 수형</typeparam> /// <param name="sources">원본 인스턴스 시퀀스</param> /// <param name="targetFactory">대상 인스턴스 생성 팩토리</param> /// <param name="mapOptions">매핑 시의 옵션</param> /// <param name="propertyNamesToExclude">제외할 속성명</param> /// <returns>매핑된 대상 객체 시퀀스</returns> public static IEnumerable <TTarget> MapObjects <TSource, TTarget>(this IEnumerable <TSource> sources, Func <TTarget> targetFactory, MapPropertyOptions mapOptions, string[] propertyNamesToExclude) { return(MapObjects(sources, targetFactory, mapOptions, null, propertyNamesToExclude)); }
/// <summary> /// 원본 인스턴스의 속성 값을 읽어와 대상 인스턴스의 속성 값을 매핑합니다. /// </summary> /// <typeparam name="TTarget">대상 인스턴스 수형</typeparam> /// <param name="source">원본 인스턴스</param> /// <param name="target">대상 인스턴스</param> /// <param name="mapOptions">매핑 시의 옵션</param> /// <param name="propertyNamesToExclude">제외할 속성명</param> public static void MapProperty <TTarget>(this object source, TTarget target, MapPropertyOptions mapOptions, string[] propertyNamesToExclude = null) { target.ShouldNotBeNull("target"); MapProperty(source, () => target, mapOptions, propertyNamesToExclude); }
/// <summary> /// 원본 인스턴스의 속성 값을 읽어와 대상 인스턴스의 속성 값을 매핑합니다. /// </summary> /// <typeparam name="TTarget">대상 인스턴스 수형</typeparam> /// <param name="source">원본 인스턴스</param> /// <param name="target">대상 인스턴스</param> /// <param name="mapOptions">매핑 시의 옵션</param> /// <param name="propertyExprsToExclude">제외할 속성명</param> public static void MapProperty <TTarget>(this object source, TTarget target, MapPropertyOptions mapOptions, params Expression <Func <TTarget, object> >[] propertyExprsToExclude) { target.ShouldNotBeNull("target"); MapProperty(source, () => target, mapOptions, propertyExprsToExclude); }
/// <summary> /// 원본 시퀀스를 이용하여 대상 객체를 생성한 후, 속성 값을 매핑하여 반환합니다. /// </summary> /// <typeparam name="TSource"></typeparam> /// <typeparam name="TTarget">대상 인스턴스 수형</typeparam> /// <param name="sources">원본 인스턴스 시퀀스</param> /// <param name="targetFactory">대상 인스턴스 생성 팩토리</param> /// <param name="mapOptions">매핑 시의 옵션</param> /// <param name="propertyExprsToExclude">제외할 속성명</param> /// <returns>매핑된 대상 객체 시퀀스</returns> public static IEnumerable <TTarget> MapObjects <TSource, TTarget>(this IEnumerable <TSource> sources, Func <TTarget> targetFactory, MapPropertyOptions mapOptions, params Expression <Func <TTarget, object> >[] propertyExprsToExclude) { return(MapObjects(sources, targetFactory, mapOptions, null, propertyExprsToExclude)); }
/// <summary> /// 원본 객체 정보를 대상 객체를 생성하여, 같은 속성명의 값을 매핑합니다. /// </summary> /// <typeparam name="TSource"></typeparam> /// <typeparam name="TTarget">대상 인스턴스 수형</typeparam> /// <param name="source">원본 인스턴스</param> /// <param name="target">대상 인스턴스</param> /// <param name="mapOptions">매핑 시의 옵션</param> /// <param name="propertyNamesToExclude">제외할 속성명</param> /// <returns>매핑된 대상 객체</returns> public static void MapObject <TSource, TTarget>(this TSource source, TTarget target, MapPropertyOptions mapOptions, string[] propertyNamesToExclude) { target.ShouldNotBeNull("target"); MapObject(source, () => target, mapOptions, null, propertyNamesToExclude); }
/// <summary> /// 원본 객체 정보를 대상 객체를 생성하여, 같은 속성명의 값을 매핑합니다. /// </summary> /// <typeparam name="TSource"></typeparam> /// <typeparam name="TTarget">대상 인스턴스 수형</typeparam> /// <param name="source">원본 인스턴스</param> /// <param name="target">대상 인스턴스</param> /// <param name="mapOptions">매핑 시의 옵션</param> /// <param name="additionalMapping">추가 매핑 작업</param> /// <param name="propertyExprsToExclude">제외할 속성명</param> /// <returns>매핑된 대상 객체</returns> public static void MapObject <TSource, TTarget>(this TSource source, TTarget target, MapPropertyOptions mapOptions, Action <TSource, TTarget> additionalMapping, params Expression <Func <TTarget, object> >[] propertyExprsToExclude) { target.ShouldNotBeNull("target"); MapObject(source, () => target, mapOptions, additionalMapping, propertyExprsToExclude); }
/// <summary> /// 원본 시퀀스를 이용하여 대상 객체를 생성한 후, 속성 값을 매핑하여 반환합니다. /// </summary> /// <typeparam name="TSource"></typeparam> /// <typeparam name="TTarget">대상 인스턴스 수형</typeparam> /// <param name="sources">원본 인스턴스 시퀀스</param> /// <param name="targetFactory">대상 인스턴스 생성 팩토리</param> /// <param name="mapOptions">매핑 시의 옵션</param> /// <param name="additionalMapping">추가 매핑 작업</param> /// <param name="propertyExprsToExclude">제외할 속성명</param> /// <returns>매핑된 대상 객체 시퀀스</returns> public static IEnumerable <TTarget> MapObjects <TSource, TTarget>(this IEnumerable <TSource> sources, Func <TTarget> targetFactory, MapPropertyOptions mapOptions, Action <TSource, TTarget> additionalMapping, params Expression <Func <TTarget, object> >[] propertyExprsToExclude) { return(sources.Select(source => MapObject(source, targetFactory, mapOptions, additionalMapping, propertyExprsToExclude))); }
/// <summary> /// 지정한 수형의 속성/필드 정보를 동적으로 접근하고 설정할 수 있는 <see cref="IDynamicAccessor"/>를 빌드합니다. /// </summary> /// <param name="type">대상 객체의 수형</param> /// <param name="mapOption">속성명/필드명 매핑 옵션</param> /// <returns></returns> public static IDynamicAccessor CreateDynamicAccessor(Type type, MapPropertyOptions mapOption) { type.ShouldNotBeNull("type"); var key = new DynamicAccessorKey(type, mapOption); return(_accessors.GetOrAdd(key, (k) => new TypeConvertableDynamicAccessor(k.TargetType, mapOption.SuppressException, mapOption.IgnoreCase))); }
/// <summary> /// 원본 시퀀스를 이용하여 대상 객체를 생성한 후, 속성 값을 매핑하여 반환합니다. /// </summary> /// <typeparam name="TSource"></typeparam> /// <typeparam name="TTarget">대상 인스턴스 수형</typeparam> /// <param name="sources">원본 인스턴스 시퀀스</param> /// <param name="targetFactory">대상 인스턴스 생성 팩토리</param> /// <param name="mapOptions">매핑 시의 옵션</param> /// <param name="additionalMapping">추가 매핑 작업</param> /// <param name="propertyNamesToExclude">제외할 속성명</param> /// <returns>매핑된 대상 객체 시퀀스</returns> public static IEnumerable <TTarget> MapObjects <TSource, TTarget>(this IEnumerable <TSource> sources, Func <TTarget> targetFactory, MapPropertyOptions mapOptions, Action <TSource, TTarget> additionalMapping, string[] propertyNamesToExclude) { foreach (var source in sources) { yield return(MapObject(source, targetFactory, mapOptions, additionalMapping, propertyNamesToExclude)); } }
/// <summary> /// 지정한 수형의 속성/필드 정보를 동적으로 접근하고 설정할 수 있는 <see cref="IDynamicAccessor{T}"/>를 빌드합니다. /// </summary> /// <typeparam name="T">대상 객체의 수형</typeparam> /// <param name="mapOption">속성명/필드명 매핑 옵션</param> /// <returns></returns> public static IDynamicAccessor <T> CreateDynamicAccessor <T>(MapPropertyOptions mapOption) { var targetType = typeof(T); var key = new DynamicAccessorKey(targetType, mapOption); return ((IDynamicAccessor <T>)_genericAccessors .GetOrAdd(key, (k) => new TypeConvertableDynamicAccessor <T>(mapOption.SuppressException, mapOption.IgnoreCase))); }
/// <summary> /// 원본 속성명-속성값 정보를 대상 인스턴스의 속성명에 값을 설정한다. /// </summary> /// <param name="source">원본 정보 (Name-Value)</param> /// <param name="targetFactory">복사 대상 인스턴스 생성 델리게이트</param> /// <param name="mapOptions">매핑 옵션</param> /// <param name="propertyNamesToExclude">복사 제외 속성 명</param> public static object Map(IDictionary source, Func <object> targetFactory, MapPropertyOptions mapOptions, params string[] propertyNamesToExclude) { targetFactory.ShouldNotBeNull("targetFactory"); var target = targetFactory(); if (IsDebugEnabled) { log.Debug("원본의 속성-값을 대상 인스턴스의 속성 값으로 복사합니다... " + @"source=[{0}], target=[{1}], mapOptions=[{2}], propertyNamesToExclude=[{3}]", source, target, mapOptions, propertyNamesToExclude.CollectionToString()); } var excludes = new List <string>(propertyNamesToExclude); var accessor = DynamicAccessorFactory.CreateDynamicAccessor(target.GetType(), mapOptions.SuppressException); var targetPropertyNames = accessor.GetPropertyNames().Except(excludes).ToList(); foreach (string name in source.Keys) { var sourceName = name; if (excludes.Any(epn => StringTool.EqualTo(epn, sourceName))) { continue; } var canSetPropertyValue = targetPropertyNames.Any(tpn => StringTool.EqualTo(tpn, sourceName)); if (canSetPropertyValue) { if (mapOptions.IgnoreCase) { var targetPropertyName = targetPropertyNames.FirstOrDefault(tpn => StringTool.EqualTo(tpn, sourceName)); if (targetPropertyName.IsNotWhiteSpace()) { accessor.SetPropertyValue(target, targetPropertyName, source[sourceName]); } } else { accessor.SetPropertyValue(target, sourceName, source[sourceName]); } } } return(target); }
/// <summary> /// 원본 객체 정보를 대상 객체를 생성하여, 같은 속성명의 값을 매핑하여 반환합니다. /// </summary> /// <typeparam name="TSource"></typeparam> /// <typeparam name="TTarget">대상 인스턴스 수형</typeparam> /// <param name="source">원본 인스턴스</param> /// <param name="targetFactory">대상 인스턴스 생성 팩토리</param> /// <param name="mapOptions">매핑 시의 옵션</param> /// <param name="additionalMapping">추가 매핑 작업</param> /// <param name="propertyNamesToExclude">제외할 속성명</param> /// <returns>매핑된 대상 객체</returns> public static TTarget MapObject <TSource, TTarget>(this TSource source, Func <TTarget> targetFactory, MapPropertyOptions mapOptions = null, Action <TSource, TTarget> additionalMapping = null, string[] propertyNamesToExclude = null) { targetFactory.ShouldNotBeNull("targetFactory"); var target = MapProperty(source, targetFactory, mapOptions, propertyNamesToExclude); if (additionalMapping != null) { additionalMapping(source, target); } return(target); }
/// <summary> /// 원본 객체 정보를 대상 객체를 생성하여, 같은 속성명의 값을 매핑하여 반환합니다. /// </summary> /// <typeparam name="TSource"></typeparam> /// <typeparam name="TTarget">대상 인스턴스 수형</typeparam> /// <param name="source">원본 인스턴스</param> /// <param name="targetFactory">대상 인스턴스 생성 팩토리</param> /// <param name="mapOptions">매핑 시의 옵션</param> /// <param name="additionalMapping">추가 매핑 작업</param> /// <param name="propertyExprsToExclude">제외할 속성명</param> /// <returns>매핑된 대상 객체</returns> public static TTarget MapObject <TSource, TTarget>(this TSource source, Func <TTarget> targetFactory, MapPropertyOptions mapOptions, Action <TSource, TTarget> additionalMapping, params Expression <Func <TTarget, object> >[] propertyExprsToExclude) { targetFactory.ShouldNotBeNull("targetFactory"); var target = MapProperty(source, targetFactory, mapOptions, propertyExprsToExclude); if (additionalMapping != null) { additionalMapping(source, target); } return(target); }
/// <summary> /// 원본 속성명-속성값 정보를 대상 인스턴스의 속성명에 값을 설정한다. /// </summary> /// <param name="source">원본 정보 (Name-Value)</param> /// <param name="targetFactory">복사 대상 인스턴스 생성 델리게이트</param> /// <param name="mapOptions">매핑 옵션</param> /// <param name="propertyNamesToExclude">복사 제외 속성 명</param> public static object Map(IDictionary source, Func<object> targetFactory, MapPropertyOptions mapOptions, params string[] propertyNamesToExclude) { targetFactory.ShouldNotBeNull("targetFactory"); var target = targetFactory(); if(IsDebugEnabled) log.Debug("원본의 속성-값을 대상 인스턴스의 속성 값으로 복사합니다... " + @"source=[{0}], target=[{1}], mapOptions=[{2}], propertyNamesToExclude=[{3}]", source, target, mapOptions, propertyNamesToExclude.CollectionToString()); var excludes = new List<string>(propertyNamesToExclude); var accessor = DynamicAccessorFactory.CreateDynamicAccessor(target.GetType(), mapOptions.SuppressException); var targetPropertyNames = accessor.GetPropertyNames().Except(excludes).ToList(); foreach(string name in source.Keys) { var sourceName = name; if(excludes.Any(epn => StringTool.EqualTo(epn, sourceName))) continue; var canSetPropertyValue = targetPropertyNames.Any(tpn => StringTool.EqualTo(tpn, sourceName)); if(canSetPropertyValue) { if(mapOptions.IgnoreCase) { var targetPropertyName = targetPropertyNames.FirstOrDefault(tpn => StringTool.EqualTo(tpn, sourceName)); if(targetPropertyName.IsNotWhiteSpace()) accessor.SetPropertyValue(target, targetPropertyName, source[sourceName]); } else { accessor.SetPropertyValue(target, sourceName, source[sourceName]); } } } return target; }
/// <summary> /// 원본 인스턴스의 속성 값을 읽어와 대상 인스턴스의 속성에 매핑합니다. /// </summary> /// <typeparam name="TTarget">대상 인스턴스 수형</typeparam> /// <param name="source">원본 인스턴스</param> /// <param name="targetFactory">대상 인스턴스 생성 함수</param> /// <param name="mapOptions">매핑 시의 옵션</param> /// <param name="propertyNamesToExclude">제외할 속성명</param> /// <result>매핑 대상 인스턴스</result> public static TTarget MapProperty <TTarget>(this object source, Func <TTarget> targetFactory, MapPropertyOptions mapOptions, string[] propertyNamesToExclude = null) { targetFactory.ShouldNotBeNull("targetFactory"); mapOptions = mapOptions ?? MapPropertyOptions.Safety; var target = targetFactory(); Guard.Assert(() => !Equals(target, default(TTarget))); if (IsDebugEnabled) { log.Debug("소스 인스턴스의 속성 정보를 대상 인스턴스[{2}]의 속성 값에 설정합니다. source=[{0}], target=[{1}]", source, target, typeof(TTarget).FullName); } var sourceAccessor = DynamicAccessorFactory.CreateDynamicAccessor(source.GetType(), mapOptions.SuppressException); var targetAccessor = DynamicAccessorFactory.CreateDynamicAccessor(target.GetType(), mapOptions.SuppressException); var excludes = (propertyNamesToExclude != null) ? new List <string>(propertyNamesToExclude) : new List <string>(); if (IsDebugEnabled) { log.Debug("속성 설젱에서 제외할 속성들=[{0}]", excludes.CollectionToString()); } var sourcePropertyNames = sourceAccessor.GetPropertyNames(); var targetPropertyNames = targetAccessor.GetPropertyNames().Except(excludes).ToList(); if (IsDebugEnabled) { log.Debug("설정할 속성들=[{0}]", targetPropertyNames.CollectionToString()); } var sourceTypeName = source.GetType().FullName; var targetTypeName = typeof(TTarget).FullName; foreach (var propertyName in targetPropertyNames) { var targetName = propertyName; if (excludes.Any(epn => epn.EqualTo(targetName))) { continue; } var sourceName = sourcePropertyNames.FirstOrDefault(spn => spn.EqualTo(targetName)); if (sourceName.IsNotWhiteSpace()) { if (mapOptions.SkipAlreadyExistValue) { var targetType = targetAccessor.GetPropertyType(targetName); var targetValue = targetAccessor.GetPropertyValue(target, targetName); if (Equals(targetValue, targetType.GetTypeDefaultValue()) == false) { if (IsDebugEnabled) { log.Debug("대상 객체의 속성[{0}]에 이미 값이 설정되어 있어, 설정을 건너뜁니다. 속성값=[{1}]", targetName, targetValue); } continue; } } if (IsDebugEnabled) { log.Debug("원본객체[{0}] => 대상객체[{1}]로 속성[{2}]의 값을 할당합니다...", sourceTypeName, targetTypeName, propertyName); } var propertyValue = sourceAccessor.GetPropertyValue(source, sourceName); targetAccessor.SetPropertyValue(target, targetName, propertyValue); if (IsDebugEnabled) { log.Debug("속성[{0}]에 할당된 값은 [{1}]입니다.", targetName, propertyValue); } } } return(target); }
public void User_MapEntitiesAsParallel_SkipAlreadyExistValue_IgnoreCase() { UnitOfWork.CurrentSessionFactory.Evict(typeof(Company)); UnitOfWork.CurrentSessionFactory.Evict(typeof(User)); UnitOfWork.CurrentSession.Clear(); var mapOptions = new MapPropertyOptions { SuppressException = true, SkipAlreadyExistValue = true, IgnoreCase = true }; var users = Repository<User>.Query().ToList(); var mappedUsers = users.MapEntitiesAsParallel(() => new UserDto { Password = "******" }, mapOptions, (user, userDto) => { userDto.CompanyCode = user.Company.Code; }, p => p.Data); Assert.AreEqual(users.Count, mappedUsers.Count); for(var i = 0; i < users.Count; i++) { Assert.AreEqual(users[i].Name, mappedUsers[i].Name, "mapping Name is fail. index=" + i); Assert.AreNotEqual(users[i].Password, mappedUsers[i].Password, "mapping Password is fail. index=" + i); Assert.AreNotEqual(users[i].Data, mappedUsers[i].Data); } }
/// <summary> /// 원본 시퀀스를 이용하여 대상 객체를 생성한 후, 병렬 방식으로 속성 값을 매핑하여 반환합니다. /// </summary> /// <typeparam name="TSource"></typeparam> /// <typeparam name="TTarget">대상 인스턴스 수형</typeparam> /// <param name="sources">원본 인스턴스 시퀀스</param> /// <param name="targetFactory">대상 인스턴스 생성 팩토리</param> /// <param name="mapOptions">매핑 시의 옵션</param> /// <param name="additionalMapping">추가 매핑 작업</param> /// <param name="propertyExprsToExclude">제외할 속성명</param> /// <returns>매핑된 대상 객체 시퀀스</returns> public static ParallelQuery <TTarget> MapObjectsAsParallel <TSource, TTarget>(this IEnumerable <TSource> sources, Func <TTarget> targetFactory, MapPropertyOptions mapOptions, Action <TSource, TTarget> additionalMapping, params Expression <Func <TTarget, object> >[] propertyExprsToExclude) { targetFactory.ShouldNotBeNull("targetFactory"); return (sources.AsParallel() .AsOrdered() .Select(source => MapObject(source, targetFactory, mapOptions, additionalMapping, propertyExprsToExclude))); }