Beispiel #1
0
        /// <summary>
        /// Describe and create decoder for given schema using reflection on target entity and provided binding flags.
        /// </summary>
        /// <typeparam name="TEntity">Entity type</typeparam>
        /// <param name="schema">Entity schema</param>
        /// <param name="bindings">Binding flags used to filter bound fields and properties</param>
        /// <returns>Entity decoder</returns>
        public static IDecoder <TEntity> CreateDecoder <TEntity>(ISchema <TEntity> schema, BindingFlags bindings)
        {
            if (!Linker.LinkDecoder(schema.DecoderDescriptor, bindings, new Dictionary <Type, object>()))
            {
                throw new ArgumentException($"can't link decoder for type '{typeof(TEntity)}'", nameof(schema));
            }

            return(schema.CreateDecoder(ConstructorGenerator.CreateConstructor <TEntity>()));
        }
Beispiel #2
0
        private static bool LinkDecoderAsObject <TEntity>(IDecoderDescriptor <TEntity> descriptor, BindingFlags bindings,
                                                          Type type, string name, object setter, IDictionary <Type, object> parents)
        {
            var constructor = MethodResolver
                              .Create <Func <object> >(() => ConstructorGenerator.CreateConstructor <object>())
                              .SetGenericArguments(type)
                              .Invoke(null);

            if (parents.TryGetValue(type, out var parent))
            {
                MethodResolver
                .Create <Func <IDecoderDescriptor <TEntity>, string, Func <object>, Setter <TEntity, object>,
                               IDecoderDescriptor <object>, IDecoderDescriptor <object> > >((d, n, c, s, p) =>
                                                                                            d.HasField(n, c, s, p))
                .SetGenericArguments(type)
                .Invoke(descriptor, name, constructor, setter, parent);

                return(true);
            }

            var fieldDescriptor = MethodResolver
                                  .Create <Func <IDecoderDescriptor <TEntity>, string, Func <object>, Setter <TEntity, object>,
                                                 IDecoderDescriptor <object> > >((d, n, c, s) => d.HasField(n, c, s))
                                  .SetGenericArguments(type)
                                  .Invoke(descriptor, name, constructor, setter);

            var result = MethodResolver
                         .Create <Func <IDecoderDescriptor <object>, BindingFlags, Dictionary <Type, object>, bool> >((d, f, p) =>
                                                                                                                      Linker.LinkDecoder(d, f, p))
                         .SetGenericArguments(type)
                         .Invoke(null, fieldDescriptor, bindings, parents);

            return(result is bool success && success);
        }
Beispiel #3
0
        private static bool LinkDecoderAsArray <TEntity>(IDecoderDescriptor <TEntity> descriptor, BindingFlags bindings,
                                                         Type type, object setter, IDictionary <Type, object> parents)
        {
            var constructor = MethodResolver
                              .Create <Func <object> >(() => ConstructorGenerator.CreateConstructor <object>())
                              .SetGenericArguments(type)
                              .Invoke(null);

            if (parents.TryGetValue(type, out var recurse))
            {
                MethodResolver
                .Create <Func <IDecoderDescriptor <TEntity>, Func <object>, Setter <TEntity, IEnumerable <object> >,
                               IDecoderDescriptor <object>, IDecoderDescriptor <object> > >((d, c, s, p) => d.HasElements(c, s, p))
                .SetGenericArguments(type)
                .Invoke(descriptor, constructor, setter, recurse);

                return(true);
            }

            var itemDescriptor = MethodResolver
                                 .Create <Func <IDecoderDescriptor <TEntity>, Func <object>, Setter <TEntity, IEnumerable <object> >,
                                                IDecoderDescriptor <object> > >((d, c, s) => d.HasElements(c, s))
                                 .SetGenericArguments(type)
                                 .Invoke(descriptor, constructor, setter);

            var result = MethodResolver
                         .Create <Func <IDecoderDescriptor <object>, BindingFlags, Dictionary <Type, object>, bool> >((d, f, p) =>
                                                                                                                      Linker.LinkDecoder(d, f, p))
                         .SetGenericArguments(type)
                         .Invoke(null, itemDescriptor, bindings, parents);

            return(result is bool success && success);
        }