How can I ignore certain fields while using UnflatLoopValueInjection

Aug 1, 2011 at 9:02 AM
Edited Aug 1, 2011 at 9:02 AM

I know that I can override the Match method in ConventionInjection, but there seems to be no such method while Unflattening. 

The only method I see that would perhaps provide me with this possibility is the AllowSetValue method, but I have no clue how to access the source property name and target property name.

Thank you very much in advance. I must admit Value Injecter has probably saved me loads of time and works like a charm so far. 

P.S. If you need some context: I'm trying to implement an "Edit" functionality in an MVC 3 Asp.Net project, that uses a DTO in the viewpage. While converting the DTO to an Entity, I get an error that the field "ID" cannot be overwritten as it is an identity field.

As I will be using this Value Injecter on other pages too, I would like to override the UnflatLoopValueInjection class so that it ignores properties that have a suffix "ID".

Aug 1, 2011 at 9:32 AM

Hi,

well, you can't do that with the UnflatLoop atm,

but

here's the code for it, so you can modify it as you will

public class UnflatLoopValueInjection : LoopValueInjectionBase
    {
        protected override void Inject(object source, object target)
        {
            foreach (PropertyDescriptor sourceProp in source.GetProps())
            {
                var prop = sourceProp;
                var endpoints = UberFlatter.Unflat(sourceProp.Name, target, t => TypesMatch(prop.PropertyType, t));

                if(endpoints.Count() == 0) continue;

                var value = sourceProp.GetValue(source);

                if (AllowSetValue(value))
                    foreach (var endpoint in endpoints)
                        endpoint.Property.SetValue(endpoint.Component, SetValue(value));
            }
        }

        protected virtual bool TypesMatch(Type sourceType, Type targetType)
        {
            return targetType == sourceType;
        }

        protected virtual object SetValue(object sourcePropertyValue)
        {
            return sourcePropertyValue;
        }
    }
//I'm going to explain the endpoints thing
there could be an unflattening from FooBarName to Foo.Bar.Name or FooBar.Name or Foo.BarName, so ther could be more than one target property (endpoint)
endpoint.Component is the Bar or FooBar or Foo.
Aug 2, 2011 at 2:07 PM

Thanks! I decided to include your source files in my project (if that's ok with you!). That way it's easier while I'm debugging or when I need to make future changes.

In case you or anyone else is interested, here's what I changed:

Class: UnflatLoopValueInjection

Original code

        protected override void Inject(object source, object target)
        {
            foreach (PropertyDescriptor sourceProp in PropertyInfosStorage.GetProps(source))
            {
                var prop = sourceProp;
                var endpoints = UberFlatter.Unflat(sourceProp.Name, target, t => TypesMatch(prop.PropertyType, t));

                if(endpoints.Count() == 0) continue;

                var value = sourceProp.GetValue(source);

                if (AllowSetValue(value))
                    foreach (var endpoint in endpoints)
                        endpoint.Property.SetValue(endpoint.Component, SetValue(value));
            }
        }

Changed code

        protected override void Inject(object source, object target)
        {
            foreach (PropertyDescriptor sourceProp in PropertyInfosStorage.GetProps(source))
            {
                var prop = sourceProp;
                var endpoints = UberFlatter.Unflat(sourceProp.Name, target, t => TypesMatch(prop.PropertyType, t));

                if(endpoints.Count() == 0) continue;

                var value = sourceProp.GetValue(source);

                //Don't overwrite properties that end with "ID".
                if (AllowSetValue(value))
                    foreach (var endpoint in endpoints)
                        if(!endpoint.Property.Name.EndsWith("ID"))
                            endpoint.Property.SetValue(endpoint.Component, SetValue(value));
            }
        }

Thanks again for the quick response!