/// <summary> /// Describe and create encoder 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 encoder</returns> public static IEncoder <TEntity> CreateEncoder <TEntity>(ISchema <TEntity> schema, BindingFlags bindings) { if (!Linker.LinkEncoder(schema.EncoderDescriptor, bindings, new Dictionary <Type, object>())) { throw new ArgumentException($"can't link encoder for type '{typeof(TEntity)}'", nameof(schema)); } return(schema.CreateEncoder()); }
private static bool LinkEncoderAsObject <TEntity>(IEncoderDescriptor <TEntity> descriptor, BindingFlags bindings, Type type, string name, object getter, IDictionary <Type, object> parents) { if (parents.TryGetValue(type, out var recurse)) { MethodResolver .Create <Func <IEncoderDescriptor <TEntity>, string, Func <TEntity, object>, IEncoderDescriptor <object>, IEncoderDescriptor <object> > >((d, n, a, p) => d.HasField(n, a, p)) .SetGenericArguments(type) .Invoke(descriptor, name, getter, recurse); return(true); } var fieldDescriptor = MethodResolver .Create <Func <IEncoderDescriptor <TEntity>, string, Func <TEntity, object>, IEncoderDescriptor <object> > >( (d, n, a) => d.HasField(n, a)) .SetGenericArguments(type) .Invoke(descriptor, name, getter); var result = MethodResolver .Create <Func <IEncoderDescriptor <object>, BindingFlags, Dictionary <Type, object>, bool> >((d, f, p) => Linker.LinkEncoder(d, f, p)) .SetGenericArguments(type) .Invoke(null, fieldDescriptor, bindings, parents); return(result is bool success && success); }