protected virtual void CreateConstructor(ModelOptions options, Type type, ClassTypeOptions typeOptions) { if (type.IsInterface) { Type concreteType; if (type.IsGenericType) { options.ConcreteTypes.TryGetValue(type.GetGenericTypeDefinition(), out concreteType); concreteType = concreteType.MakeGenericType(type.GetGenericArguments()); } else { options.ConcreteTypes.TryGetValue(type.GetGenericTypeDefinition(), out concreteType); } typeOptions.Constructor = Lambda(New(concreteType)); } else if (type.IsClass && type.GetConstructor(new Type[0]) != null) { typeOptions.Constructor = Lambda(New(type)); } }
public ITypeOptions Create(ModelOptions options, Type type) { ClassTypeOptions typeOptions = new ClassTypeOptions(); typeOptions.Type = type; // determine the object type: Entity (has members), Collection or Plain Value if (IsPrimitive(options, type)) { typeOptions.IsValue = true; } else if (type.IsEnumerable(out Type itemType)) { typeOptions.ItemType = itemType; typeOptions.IsCollection = true; } else { typeOptions.IsComplexType = true; // generate members. foreach (PropertyInfo propInfo in type.GetRuntimeProperties()) { if (ShouldMap(propInfo)) { ClassMemberOptions memberOptions = new ClassMemberOptions(); memberOptions.Name = propInfo.Name; memberOptions.Type = propInfo.PropertyType; // generate getter. if (propInfo.CanRead) { memberOptions.Getter = Lambda( Parameter(type, out Expression instanceExpr), Property(instanceExpr, propInfo) ); } // generate setter. if (propInfo.CanWrite) { memberOptions.Setter = Lambda( Parameter(type, out Expression instanceExpr), Parameter(propInfo.PropertyType, out Expression valueExpr), Assign(Property(instanceExpr, propInfo), valueExpr) ); } // apply member attributes. foreach (Attribute annotation in propInfo.GetCustomAttributes()) { if (options.AnnotationHandlers.TryGetValue(annotation.GetType(), out IAnnotationHandler handler)) { handler.Apply(annotation, options, typeOptions, memberOptions); } } typeOptions.Members.Add(memberOptions); } } } CreateConstructor(options, type, typeOptions); // apply type attributes. foreach (Attribute annotation in type.GetCustomAttributes()) { if (options.AnnotationHandlers.TryGetValue(annotation.GetType(), out IAnnotationHandler handler)) { handler.Apply(annotation, options, typeOptions, null); } } // apply conventions. foreach (ITypeOptionsConvention convention in options.Conventions) { convention.Apply(options, typeOptions); } // manual configuration is applied after all of this. return(typeOptions); }