1

I am having trouble understating if this is a basic feature on omu.valueinjecter. I have 2 identical Classes (difference is basically namespaces) and the Source class has public fields instead of public properties.

Is it possible to make ValueInjecter map the public fields?

Thanks

  • 1
    it maps properties to properties, you want fields to properties, for this you could implement IValueInjection (loop through the fields/props ) and use it like `target.InjectFrom(source);` – Omu Oct 27 '15 at 14:00
  • Thanks, I will try it. I guess it's the same way if properties to fields? – Carlos Magno Rosa Oct 27 '15 at 15:25
  • 1
    yes, the same, just implement IValueInjection – Omu Oct 27 '15 at 17:20

1 Answers1

2

For those of you who are after a copy-paste solution:

public class PropertyAndFieldInjection : ValueInjection
{
    protected string[] ignoredProps;

    public PropertyAndFieldInjection()
    {
    }

    public PropertyAndFieldInjection(string[] ignoredProps)
    {
        this.ignoredProps = ignoredProps;
    }

    protected override void Inject(object source, object target)
    {
        var sourceProps = source.GetType().GetProps();
        foreach (var sourceProp in sourceProps)
        {
            Execute(sourceProp, source, target);
        }

        var sourceFields = source.GetType().GetFields();
        foreach (var sourceField in sourceFields)
        {
            Execute(sourceField, source, target);
        }
    }

    protected virtual void Execute(PropertyInfo sp, object source, object target)
    {
        if (!sp.CanRead || sp.GetGetMethod() == null || (ignoredProps != null && ignoredProps.Contains(sp.Name)))
            return;

        var tp = target.GetType().GetProperty(sp.Name);
        if (tp != null && tp.CanWrite && tp.PropertyType == sp.PropertyType && tp.GetSetMethod() != null)
        {
            tp.SetValue(target, sp.GetValue(source, null), null);
            return;
        }

        var tf = target.GetType().GetField(sp.Name);
        if (tf != null && tf.FieldType == sp.PropertyType)
        {
            tf.SetValue(target, sp.GetValue(source, null));
        }
    }

    protected virtual void Execute(FieldInfo sf, object source, object target)
    {
        if (ignoredProps != null && ignoredProps.Contains(sf.Name))
            return;

        var tf = target.GetType().GetField(sf.Name);
        if (tf != null && tf.FieldType == sf.FieldType)
        {
            tf.SetValue(target, sf.GetValue(source));
            return;
        }

        var tp = target.GetType().GetProperty(sf.Name);
        if (tp != null && tp.CanWrite && tp.PropertyType == sf.FieldType && tp.GetSetMethod() != null)
        {
            tp.SetValue(target, sf.GetValue(source), null);
        }
    }
}

This works in all 4 directions (prop->prop, prop<->field, field->field). I didn't test it thoroughly so use it at your own risk.

Zar Shardan
  • 5,675
  • 2
  • 39
  • 37