public void CreateDynamicAccessor_Generic() { TestTool.RunTasks(ThreadCount, () => { var gzipAccessor = DynamicAccessorFactory.CreateDynamicAccessor <GZipCompressor>(); Assert.IsNotNull(gzipAccessor); var deflateAccessor = DynamicAccessorFactory.CreateDynamicAccessor <DeflateCompressor>(); Assert.IsNotNull(deflateAccessor); }); }
public void CreateDynamicAccessor_By_Type() { TestTool.RunTasks(ThreadCount, () => { var gzipAccessor = DynamicAccessorFactory.CreateDynamicAccessor(typeof(GZipCompressor)); Assert.IsNotNull(gzipAccessor); var deflateAccessor = DynamicAccessorFactory.CreateDynamicAccessor(typeof(DeflateCompressor)); Assert.IsNotNull(deflateAccessor); }); }
public void SetFieldByDynamicMethod() { using (new OperationTimer("Set Field value by dynamic method")) { var accessor = DynamicAccessorFactory.CreateDynamicAccessor(typeof(Widget)); foreach (var widget in _widgets) { accessor.SetFieldValue(widget, "_id", widget.Id); accessor.SetFieldValue(widget, "_name", widget.Name); accessor.SetFieldValue(widget, "_guid", widget.Guid); } } }
/// <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); }
public void GetFieldByDynamicMethod() { using (new OperationTimer("Get Field by Dynamic Method")) { var accessor = DynamicAccessorFactory.CreateDynamicAccessor(typeof(Widget)); foreach (var widget in _widgets) { var id = (int)accessor.GetFieldValue(widget, "_id"); var name = (string)accessor.GetFieldValue(widget, "_name"); var guid = (Guid)accessor.GetFieldValue(widget, "_guid"); Assert.AreEqual(id, widget.Id); Assert.AreEqual(name, widget.Name); Assert.AreEqual(guid, widget.Guid); } } }
public void TryGetPropertyByDynamicMethod() { using (new OperationTimer("TryGetPropertyValue by Dynamic Method")) { var accessor = DynamicAccessorFactory.CreateDynamicAccessor(typeof(Widget)); foreach (var widget in _widgets) { object id, name, guid; Assert.IsTrue(accessor.TryGetPropertyValue(widget, "Id", out id)); Assert.IsTrue(accessor.TryGetPropertyValue(widget, "Name", out name)); Assert.IsTrue(accessor.TryGetPropertyValue(widget, "Guid", out guid)); object notExists; Assert.IsFalse(accessor.TryGetFieldValue(widget, "NotExistProperty", out notExists)); Assert.AreEqual(id, widget.Id); Assert.AreEqual(name, widget.Name); Assert.AreEqual(guid, widget.Guid); } } }
/// <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); }
/// <summary> /// 지정된 객체의 속성 정보를 "속성명=속성값" 형태의 문자열로 빌드한다. /// </summary> /// <param name="instance"></param> /// <param name="showCollections"></param> /// <returns></returns> public static string ObjectToString(this object instance, bool showCollections = false) { if (ReferenceEquals(instance, null)) { return(string.Empty); } var sb = new StringBuilder(); try { var instanceType = instance.GetType(); #if !SILVERLIGHT var accessor = DynamicAccessorFactory.CreateDynamicAccessor(instanceType, true); #endif // object 의 type name을 표시한다. sb.Append(instanceType.FullName).Append("#"); var first = true; foreach (var pi in GetPropertyInfos(instanceType)) { if (first == false) { sb.Append(PropertyDelimiter); } #if !SILVERLIGHT // 속성중 ValueType, Enum, string 형식만을 제공한다. if (pi.PropertyType.IsValueType || pi.PropertyType.IsEnum || pi.PropertyType.Equals(typeof(string))) { sb.AppendFormat(ValueFormat, pi.Name, accessor.GetPropertyValue(instance, pi.Name)); } if (showCollections) { if (pi.PropertyType.IsAssignableFrom(typeof(IDictionary))) { sb.AppendFormat(ValueFormat, pi.Name, DictionaryToString(accessor.GetPropertyValue(instance, pi.Name) as IDictionary)); } else if (pi.PropertyType.IsAssignableFrom(typeof(IEnumerable))) { sb.AppendFormat(ValueFormat, pi.Name, CollectionToString(accessor.GetPropertyValue(instance, pi.Name) as IEnumerable)); } } #else // 속성중 ValueType, Enum, string 형식만을 제공한다. if (pi.PropertyType.IsValueType || pi.PropertyType.IsEnum || pi.PropertyType.Equals(typeof(string))) { sb.AppendFormat(ValueFormat, pi.Name, instanceType.GetProperty(pi.Name).GetValue(instance, null)); } if (showCollections) { if (pi.PropertyType.IsAssignableFrom(typeof(IDictionary))) { sb.AppendFormat(ValueFormat, pi.Name, DictionaryToString(instanceType.GetProperty(pi.Name).GetValue(instance, null) as IDictionary)); } else if (pi.PropertyType.IsAssignableFrom(typeof(IEnumerable))) { sb.AppendFormat(ValueFormat, pi.Name, CollectionToString(instanceType.GetProperty(pi.Name).GetValue(instance, null) as IEnumerable)); } } #endif if (first) { first = false; } } } catch (Exception ex) { if (log.IsWarnEnabled) { log.WarnException("객체를 문자열로 빌드하는데 실패했습니다.", ex); } } return(sb.ToString()); }
/// <summary> /// 지정된 인스턴스에 대해 필드, 속성 값을 조작할 수 있는 <see cref="IDynamicAccessor"/>를 생성합니다. /// </summary> /// <param name="instance"></param> /// <returns></returns> public static IDynamicAccessor GetDynamicAccessor(this object instance) { instance.ShouldNotBeNull("instance"); return(DynamicAccessorFactory.CreateDynamicAccessor(instance.GetType())); }
/// <summary> /// 지정된 수형의 인스턴스의 필드와 속성 정보를 동적으로 접근할 수 있는 <see cref="IDynamicAccessor"/>를 제공해줍니다. /// </summary> /// <param name="instanceType"></param> /// <returns></returns> public static IDynamicAccessor GetDynamicAccessor(this Type instanceType) { instanceType.ShouldNotBeNull("instanceType"); return(DynamicAccessorFactory.CreateDynamicAccessor(instanceType, false)); }