2
using System.Diagnostics;
4
using System.Reflection;
5
using ServiceStack.Common.Utils;
7
namespace ServiceStack.Common
9
public static class ReflectionExtensions
11
public static To PopulateWith<To, From>(this To to, From from)
13
return ReflectionUtils.PopulateObject(to, from);
16
public static To PopulateWithNonDefaultValues<To, From>(this To to, From from)
18
return ReflectionUtils.PopulateWithNonDefaultValues(to, from);
21
public static To PopulateFromPropertiesWithAttribute<To, From, TAttr>(this To to, From from)
23
return ReflectionUtils.PopulateFromPropertiesWithAttribute(to, from, typeof(TAttr));
26
public static T TranslateTo<T>(this object from)
30
return to.PopulateWith(from);
33
public static TAttribute FirstAttribute<TAttribute>(this Type type)
35
return type.FirstAttribute<TAttribute>(true);
38
public static TAttribute FirstAttribute<TAttribute>(this Type type, bool inherit)
40
var attrs = type.GetCustomAttributes(typeof(TAttribute), inherit);
41
return (TAttribute)(attrs.Length > 0 ? attrs[0] : null);
44
public static TAttribute FirstAttribute<TAttribute>(this PropertyInfo propertyInfo)
46
return propertyInfo.FirstAttribute<TAttribute>(true);
49
public static TAttribute FirstAttribute<TAttribute>(this PropertyInfo propertyInfo, bool inherit)
51
var attrs = propertyInfo.GetCustomAttributes(typeof(TAttribute), inherit);
52
return (TAttribute)(attrs.Length > 0 ? attrs[0] : null);
55
public static bool IsGenericType(this Type type)
59
if (type.IsGenericType)
67
public static Type FirstGenericTypeDefinition(this Type type)
71
if (type.IsGenericType)
72
return type.GetGenericTypeDefinition();
80
public static bool IsDynamic(this Assembly assembly)
87
var isDyanmic = assembly is System.Reflection.Emit.AssemblyBuilder
88
|| string.IsNullOrEmpty(assembly.Location);
91
catch (NotSupportedException)
93
//Ignore assembly.Location not supported in a dynamic assembly.
99
public static bool IsDebugBuild(this Assembly assembly)
101
return assembly.GetCustomAttributes(false)
102
.OfType<DebuggableAttribute>()
103
.Select(attr => attr.IsJITTrackingEnabled)
110
#if FALSE && DOTNET35
111
//Efficient POCO Translator from: http://www.yoda.arachsys.com/csharp/miscutil/
113
using System.Collections.Generic;
114
using System.Linq.Expressions;
115
using System.Reflection;
117
namespace MiscUtil.Reflection
120
/// Generic class which copies to its target type from a source
121
/// type specified in the Copy method. The types are specified
122
/// separately to take advantage of type inference on generic
123
/// method arguments.
125
public static class PropertyCopy<TTarget> where TTarget : class, new()
128
/// Copies all readable properties from the source to a new instance
131
public static TTarget CopyFrom<TSource>(TSource source) where TSource : class
133
return PropertyCopier<TSource>.Copy(source);
137
/// Static class to efficiently store the compiled delegate which can
138
/// do the copying. We need a bit of work to ensure that exceptions are
139
/// appropriately propagated, as the exception is generated at type initialization
140
/// time, but we wish it to be thrown as an ArgumentException.
142
private static class PropertyCopier<TSource> where TSource : class
144
private static readonly Func<TSource, TTarget> copier;
145
private static readonly Exception initializationException;
147
internal static TTarget Copy(TSource source)
149
if (initializationException != null)
151
throw initializationException;
155
throw new ArgumentNullException("source");
157
return copier(source);
160
static PropertyCopier()
164
copier = BuildCopier();
165
initializationException = null;
170
initializationException = e;
174
private static Func<TSource, TTarget> BuildCopier()
176
ParameterExpression sourceParameter = Expression.Parameter(typeof(TSource), "source");
177
var bindings = new List<MemberBinding>();
178
foreach (PropertyInfo sourceProperty in typeof(TSource).GetProperties())
180
if (!sourceProperty.CanRead)
184
PropertyInfo targetProperty = typeof(TTarget).GetProperty(sourceProperty.Name);
185
if (targetProperty == null)
187
throw new ArgumentException("Property " + sourceProperty.Name + " is not present and accessible in " + typeof(TTarget).FullName);
189
if (!targetProperty.CanWrite)
191
throw new ArgumentException("Property " + sourceProperty.Name + " is not writable in " + typeof(TTarget).FullName);
193
if (!targetProperty.PropertyType.IsAssignableFrom(sourceProperty.PropertyType))
195
throw new ArgumentException("Property " + sourceProperty.Name + " has an incompatible type in " + typeof(TTarget).FullName);
197
bindings.Add(Expression.Bind(targetProperty, Expression.Property(sourceParameter, sourceProperty)));
199
Expression initializer = Expression.MemberInit(Expression.New(typeof(TTarget)), bindings);
200
return Expression.Lambda<Func<TSource,TTarget>>(initializer, sourceParameter).Compile();