/// <summary> /// The type initialization /// </summary> private static void Initialize() { var properties = typeof(TObject).GetProperties( BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty | BindingFlags.SetProperty); foreach (var property in properties) { var publishAttribute = property.GetCustomAttribute <DeclareFieldAttribute>(); if (publishAttribute == null || !publishAttribute.Access.HasFlag(EnAccessFlag.Writable)) { continue; } var propertyName = publishAttribute.Name ?? ApiDescriptionAttribute.ToCamelCase(property.Name); var destination = Expression.Parameter(typeof(TObject), "d"); var source = Expression.Parameter(typeof(TObject), "s"); var json = Expression.Parameter(typeof(JObject), "json"); if (property.PropertyType.GetTypeInfo().IsPrimitive || DataUpdaterConfig.AdditionalScalarTypes.Contains(property.PropertyType) || DataUpdaterConfig.AdditionalScalarTypes.Any(t => property.PropertyType.GetTypeInfo().IsSubclassOf(t)) || property.PropertyType.GetTypeInfo().GetInterface("System.Collections.IEnumerable") != null) { // creating direct copy var copy = Expression.Assign( Expression.Property(destination, property), Expression.Property(source, property)); var lambda = Expression.Lambda <Action <TObject, TObject, JObject> >(copy, destination, source, json); PropertyCopiers[propertyName] = lambda.Compile(); } else { var updaterType = typeof(DataUpdater <>).MakeGenericType(property.PropertyType); var method = updaterType.GetMethod( nameof(Update), new[] { property.PropertyType, property.PropertyType, typeof(JObject) }); var recursiveCopy = Expression.Call( null, method, Expression.Property(destination, property), Expression.Property(source, property), json); var assign = Expression.Assign( Expression.Property(destination, property), Expression.Property(source, property)); var copy = Expression.IfThenElse( Expression.Equal(Expression.Property(destination, property), Expression.Constant(null)), assign, recursiveCopy); var lambda = Expression.Lambda <Action <TObject, TObject, JObject> >(copy, destination, source, json); PropertyCopiers[propertyName] = lambda.Compile(); } } }
/// <summary> /// Initializes static members of the <see cref="PathCreator{T, TContext}"/> class. /// </summary> /// <param name="context"> /// The data context. /// </param> private static void Initialize(TContext context) { if (isInitialized) { return; } lock (LockObject) { if (isInitialized) { return; } isInitialized = true; var entityType = context.Model.FindEntityType(typeof(T)); if (entityType == null) { return; } foreach (var navigation in entityType.GetNavigations()) { var declareFieldAttribute = navigation.PropertyInfo.GetCustomAttribute <DeclareFieldAttribute>(); var propertyName = declareFieldAttribute?.Name ?? ApiDescriptionAttribute.ToCamelCase(navigation.PropertyInfo.Name); var toManyType = navigation.PropertyInfo.PropertyType.GetInterfaces() .FirstOrDefault( i => i.GetTypeInfo().IsGenericType && i.GetGenericTypeDefinition() == typeof(IEnumerable <>)) ?.GetGenericArguments()[0]; if (toManyType != null) { NavigationProperties[propertyName] = new PropertyDescription <TContext>(navigation.Name, toManyType, EnRelationType.OneToMany); } else { NavigationProperties[propertyName] = new PropertyDescription <TContext>( navigation.Name, navigation.PropertyInfo.PropertyType, EnRelationType.OneToOne); } } } }