public virtual DataModelBindingBuilder <TSourceModel, TSourceField, TTargetModel, TTargetField> Bind(ModelFieldBindingTarget <TTargetField> bindingTarget, ModelFieldBindingSource <TSourceField> bindingSource, DataModelBinding <TSourceField, TTargetField> binding) { var sourcePathBase = bindingSource.Path; var targetPathBase = bindingTarget.Path; foreach (var inputFieldBinding in binding.FieldBindings) { var target = new ModelFieldBindingTarget <TTargetField>( targetPathBase.Concat(inputFieldBinding.BindingTarget.Path).ToArray(), inputFieldBinding.TargetField ); if (IsBound(target)) { continue; } var source = new ModelFieldBindingSource <TSourceField>( sourcePathBase.Concat(inputFieldBinding.BindingSource.Path).ToArray(), inputFieldBinding.SourceField ); var fieldBinding = new ModelFieldBinding <TSourceField, TTargetField>( source, target, inputFieldBinding.Transformation ); FieldBindings.Add(fieldBinding); } return(this); }
public virtual DataModelBindingBuilder <TSourceModel, TSourceField, TTargetModel, TTargetField> Bind(ModelFieldBindingTarget <TTargetField> bindingTarget, ModelFieldBindingSource <TSourceField> bindingSource, IBindingTransformFactory bindingTransformFactory) { if (bindingSource == null) { throw new ArgumentNullException(nameof(bindingSource)); } if (bindingTarget == null) { throw new ArgumentNullException(nameof(bindingTarget)); } var bindingTransformation = bindingTransformFactory.CreateTransformation( bindingSource.Field, bindingTarget.Field ); var fieldBinding = new ModelFieldBinding <TSourceField, TTargetField>( bindingSource, bindingTarget, bindingTransformation ); FieldBindings.Add(fieldBinding); return(this); }
RouteBindingFromSourceType<TSourceModel, TSourceField, TIntermediateModel, TTargetModel, TTargetField>( this DataModelBinding<TSourceModel, TSourceField, TIntermediateModel, TTargetField> sourceToIntermediateBinding, DataModelBinding<TIntermediateModel, TTargetField, TTargetModel, TTargetField> intermediateToTargetBinding ) where TSourceField : IModelField where TTargetField : IModelField where TSourceModel : IDataModel<TSourceField> where TIntermediateModel : TypeModel, IDataModel<TTargetField> where TTargetModel : IDataModel<TTargetField> { // this method needs TIntermediateModel to be a TypeModel // a TypeModel is required because we're performing a transform on // an already transformed value // for now the method is left without a generic constraint on TIntermediateModel // forcing the use of TypeModel so that I can come back to it // as needed at a later date. // in the future, consider allowing the consumer to pass in a binding // that binds TIntermediate to a TypeModel that can be used to transform // bound objects var fieldBindings = new List<ModelFieldBinding<TSourceField, TTargetField>>(); // loop each field bound from source->intermediate foreach (var sourceBinding in sourceToIntermediateBinding.FieldBindings) { // find a matching binding from intermediate->target var targetBinding = intermediateToTargetBinding.FieldBindings .FirstOrDefault(q => q.BindingSource.Path.SequenceEqual(sourceBinding.BindingTarget.Path)); if (targetBinding != null) { // copy binding var routedBinding = new ModelFieldBinding<TSourceField, TTargetField>( sourceBinding.BindingSource, targetBinding.BindingTarget, new CompositeBindingTransformFactory(sourceBinding.Transformation, targetBinding.Transformation) .CreateTransformation(sourceBinding.SourceField, targetBinding.TargetField) ); fieldBindings.Add(routedBinding); continue; } var deeperModel = sourceBinding.TargetField.FieldModel; if (deeperModel == null) continue; var runOnceSourceTransform = RunOnceTransformation.Create(sourceBinding.Transformation); BindIntermediateFields(runOnceSourceTransform, sourceBinding, deeperModel, new IModelField[0], sourceBinding.BindingTarget.Path); } return new DataModelBinding<TSourceModel, TSourceField, TTargetModel, TTargetField>( sourceToIntermediateBinding.SourceModel, intermediateToTargetBinding.TargetModel, fieldBindings ); void BindIntermediateFields(BindingTransformation sourceTransform, ModelFieldBinding<TSourceField, TTargetField> sourceBinding, IDataModel model, IEnumerable<IModelField> pathOfFields, string[] sourceBindingPath) { foreach (var field in model.Fields) { var thisPathOfFields = pathOfFields.Concat(new[] { field }); var intermediateBindingPath = sourceBindingPath.Concat(thisPathOfFields.Select(q => q.FieldName)) .ToArray(); var targetBinding = intermediateToTargetBinding.FieldBindings .FirstOrDefault(q => q.BindingSource.Path.SequenceEqual(intermediateBindingPath)); if (targetBinding != null) { var routedBinding = new ModelFieldBinding<TSourceField, TTargetField>( sourceBinding.BindingSource, targetBinding.BindingTarget, new CompositeBindingTransformFactory( sourceTransform, ReadFieldTransform.Create(thisPathOfFields.OfType<PropertyField>().ToArray()), targetBinding.Transformation) .CreateTransformation(sourceBinding.SourceField, targetBinding.TargetField) ); fieldBindings.Add(routedBinding); continue; } var deeperModel = field.FieldModel; if (deeperModel == null) continue; BindIntermediateFields(sourceTransform, sourceBinding, deeperModel, thisPathOfFields, sourceBinding.BindingTarget.Path); } } }