コード例 #1
0
        /// <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();
                }
            }
        }
コード例 #2
0
        /// <summary>
        /// Initializes static members of the <see cref="EnumResolver{T}"/> class.
        /// </summary>
        static EnumResolver()
        {
            var type = typeof(T);

            if (!type.GetTypeInfo().IsSubclassOf(typeof(Enum)))
            {
                throw new Exception($"{type.Name} should be enum");
            }

            var names        = Enum.GetNames(type);
            var descriptions = new Dictionary <string, string>();

            foreach (var name in names)
            {
                var property  = type.GetTypeInfo().GetMember(name).FirstOrDefault();
                var attribute = property?.GetCustomAttribute <ApiDescriptionAttribute>();
                if (attribute != null)
                {
                    descriptions[name] = attribute.Description;
                }
            }

            GeneratedType = new ApiEnumType(ApiDescriptionAttribute.GetTypeName(type), names, descriptions);
            hasFlags      = type.GetTypeInfo().GetCustomAttribute <FlagsAttribute>() != null;
        }
コード例 #3
0
        /// <summary>
        /// Initializes static members of the <see cref="CollectionResolver{T}"/> class.
        /// </summary>
        static CollectionResolver()
        {
            FilterType = new ApiObjectType($"{ApiDescriptionAttribute.GetTypeName(typeof(T))}_Filter");
            SortType   = new ApiEnumType($"{ApiDescriptionAttribute.GetTypeName(typeof(T))}_Sort");

            var param = Expression.Parameter(typeof(T));

            GetIdValue =
                Expression.Lambda <Func <T, object> >(
                    Expression.Convert(Expression.Property(param, NodeMetaData.KeyProperty), typeof(object)),
                    param).Compile();

            InitializeType();
        }
コード例 #4
0
            /// <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);
                        }
                    }
                }
            }
コード例 #5
0
        /// <summary>
        /// Parses the metadata of returning type for the field
        /// </summary>
        /// <param name="type">The original field return type</param>
        /// <param name="attribute">The description attribute</param>
        /// <returns>The type metadata</returns>
        public static TypeMetadata GenerateTypeMetadata(Type type, PublishToApiAttribute attribute)
        {
            var metadata  = new TypeMetadata();
            var asyncType = ApiDescriptionAttribute.CheckType(type, typeof(Task <>));

            if (asyncType != null)
            {
                metadata.IsAsync = true;
                type             = asyncType.GenericTypeArguments[0];
            }

            var converter = (attribute as DeclareFieldAttribute)?.Converter;

            if (attribute.ReturnType != null)
            {
                type = attribute.ReturnType;
                metadata.IsForwarding = true;
            }
            else if (converter != null)
            {
                var valueConverter =
                    converter.GetInterfaces()
                    .FirstOrDefault(
                        i => i.GetTypeInfo().IsGenericType&& i.GetGenericTypeDefinition() == typeof(IValueConverter <>));
                if (valueConverter == null)
                {
                    throw new InvalidOperationException(
                              $"Converter {converter.FullName} should implement the IValueConverter<>");
                }

                type = valueConverter.GenericTypeArguments[0];
                metadata.ConverterType = converter;
            }

            var nullable = ApiDescriptionAttribute.CheckType(type, typeof(Nullable <>));

            if (nullable != null)
            {
                type = nullable.GenericTypeArguments[0];
            }

            var scalarType = CheckScalarType(type);

            metadata.MetaType = EnMetaType.Scalar;
            if (scalarType == EnScalarType.None)
            {
                var enumerable = ApiDescriptionAttribute.CheckType(type, typeof(IEnumerable <>));
                var connection = ApiDescriptionAttribute.CheckType(type, typeof(INodeConnection <>));

                if (connection != null)
                {
                    metadata.MetaType           = EnMetaType.Connection;
                    metadata.RealConnectionType = type;
                    type       = connection.GenericTypeArguments[0];
                    scalarType = CheckScalarType(type);
                }
                else if (enumerable != null)
                {
                    metadata.MetaType = EnMetaType.Array;
                    type       = enumerable.GenericTypeArguments[0];
                    scalarType = CheckScalarType(type);
                }
                else
                {
                    metadata.MetaType = EnMetaType.Object;
                }
            }

            if (scalarType != EnScalarType.None && type.GetTypeInfo().IsSubclassOf(typeof(Enum)))
            {
                type = Enum.GetUnderlyingType(type);
            }

            // todo: check forwarding type
            metadata.ScalarType = scalarType;
            metadata.Type       = type;

            if (metadata.ScalarType == EnScalarType.None && !type.GetTypeInfo().IsSubclassOf(typeof(Enum)))
            {
                var keyProperty =
                    type.GetProperties(BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance)
                    .FirstOrDefault(p => p.GetCustomAttribute <DeclareFieldAttribute>()?.IsKey == true);
                if (keyProperty != null)
                {
                    metadata.KeyProperty     = keyProperty;
                    metadata.KeyPropertyName = PublishToApiAttribute.GetMemberName(keyProperty);
                }
            }

            var typeName = ApiDescriptionAttribute.GetTypeName(type);

            metadata.TypeName = typeName;
            ////metadata.TypeName = metadata.GetFlags().HasFlag(EnFieldFlags.IsConnection) ? $"{typeName}_Connection" : typeName;
            return(metadata);
        }