private static ImmutableList <ProductAnchorProjection> DeserializeCompoundProjection( Emitter emitter, CompoundProjection compoundProjection, Type type, ImmutableList <Product> products, Product anchor, string collectionName) { var constructorInfos = type.GetConstructors(); if (constructorInfos.Length != 1) { throw new NotImplementedException($"Multiple constructors for {type.Name}"); } var constructor = constructorInfos.Single(); var parameters = constructor.GetParameters(); if (parameters.Any()) { var productProjections = from product in products let result = constructor.Invoke(( from parameter in parameters let projection = compoundProjection.GetProjection(parameter.Name) select DeserializeParameter(emitter, projection, parameter.ParameterType, parameter.Name, product) ).ToArray()) select new ProductAnchorProjection(product, anchor, result, collectionName); return(productProjections.ToImmutableList()); } else { var properties = type.GetProperties(); var productProjections = products.Select(product => { return(DeserializeProducts(emitter, compoundProjection, type, product, properties, anchor, collectionName)); }); var childProductProjections = from product in products let parentAnchor = product.GetAnchor() from property in properties where !property.PropertyType.IsFactType() && property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() == typeof(IObservableCollection <>) let projection = compoundProjection.GetProjection(property.Name) where projection is CollectionProjection let collectionProjection = (CollectionProjection)projection where product.Names.Contains(property.Name) let element = product.GetElement(property.Name) where element is CollectionElement let collectionElement = (CollectionElement)element from childProductProjection in DeserializeChildParameters(emitter, collectionProjection.Specification.Projection, property.PropertyType, property.Name, collectionElement.Products, parentAnchor) select childProductProjection; return(productProjections.Concat(childProductProjections).ToImmutableList()); } }
private static ProductAnchorProjection DeserializeProducts( Emitter emitter, CompoundProjection compoundProjection, Type type, Product product, PropertyInfo[] properties, Product anchor, string collectionName) { var result = Activator.CreateInstance(type); foreach (var property in properties) { var projection = compoundProjection.GetProjection(property.Name); var value = DeserializeParameter(emitter, projection, property.PropertyType, property.Name, product); property.SetValue(result, value); } return(new ProductAnchorProjection(product, anchor, result, collectionName)); }