Ignore properties on InjectFrom?

Nov 15, 2010 at 11:38 AM

When when injecting from one class to another and there is a property that is matched can you ignore easily?

I.e.

Class1{Name = "Kohan", Age = null}

Class2{Name = null, Age = 26}

Class1.InjectFrom(Class2);

I want to ignore Name injection and keep Class1.Name = Kohan - but inject Age as desired.

Many thanks.

Nov 15, 2010 at 12:18 PM

in case you want to ignore because it's value is null you can use this injection:

    public class NoName : LoopValueInjection
    {
        protected override bool UseSourceProp(string sourcePropName)
        {
            return sourcePropName != "Name";
        }

    }

if because it's called "Name" this:

    public class NoNullsLoop : LoopValueInjection
    {
        protected override bool AllowSetValue(object value)
        {
            return value != null;
        }
    }

or something more generic

public class My : LoopValueInjection
    {
        private string[] ignore;

        public My Ignore(string[] ignore)
        {
            this.ignore = ignore;
            return this;
        }

        protected override bool UseSourceProp(string sourcePropName)
        {
            return !ignore.Contains(sourcePropName);
        }
    }
    
    //and use like this
    //aa.InjectFrom(new My().Ignore(new[]{"Name","Surname"});



Nov 15, 2010 at 12:33 PM

Thanks, i'll give it a try.

As a feature it would be cool to have Ignore Nulls as an overload on the injection. Seems to be something i would use a lot.

Dec 15, 2010 at 7:16 PM

+1 for an Ignore Nulls option.

Dec 16, 2010 at 7:26 AM

if you do:

        protected override bool AllowSetValue(object value)
{
return value != null;
}

the null values are going to be ignored,

if you do:

        protected override bool AllowSetValue(object value)
{
return value != null && value.ToString() != "hi";
}
the null and "hi" values are going to be ignored, etc.
Jan 10, 2011 at 5:14 PM

Realised today that this method will fall over if object value is a class with it's own properties that are null.

They will be injected.

Jan 10, 2011 at 7:27 PM

you got the value, check it for null, or check it for his properties (if it has them) for null, or whatever you need

Jan 24, 2011 at 12:16 PM

While overall VI is working fine, I've noticed this pattern of creating valueinjections for everything we need and it is quickly becoming an "overkill" or maintainence headache. My ValueInjections.cs file is growing beyond reasonable length.

So some more overloads like this one for nulls would be appreciated.

Jan 24, 2011 at 12:41 PM
Edited Jan 24, 2011 at 12:41 PM

@markoh could you post your ValueInjections.cs in a discussion, I would like to see it

Jan 24, 2011 at 1:19 PM

I see no point of doing it because, no offense, but you never actually took a look at Entity Framework v4 entities and, from the few discussions we had, I can see you don't quite get the problems we face when using those entities. For instance, when you use EF you actually have to create a custom value injection for each navigation property you want to exclude/ignore because otherwise it will rewrite it with a null reference (the POSTed model might have a null value for certain navigation property but the object we are editing might not and we might want to keep it's value). Even if the POSTed model has values for navigation property, VI should still not touch them because we have to manually set either the foreign key or load the entity from the DB by its primary key and set it to the navigation property. Again, if we don't want VI to touch it, we need custom value injection. It's something like the "exclude" parameter on MVC's UpdateModel() function. I thought using VI will allow me to get rid of this special excludes.

If I put it as simple as possible, the behaviour I would need is to only copy value types and even in that case only when the source is not null.

Jan 24, 2011 at 1:45 PM

   I actually did spent a lot of time looking at those classes, but I didn't saw any reason for using vi in there

about ignoring proprieties you could do something like this:

public class My : LoopValueInjection
    {
        private IEnumerable<string> ignores;

        public My Ignore(string[] s)
        {
            ignores = s;
            return this;
        }

        protected override bool UseSourceProp(string sourcePropName)
        {
            return !ignores.Contains(sourcePropName);
        }
    }

and use it like this:

a.InjectFrom(new My(new[]{"Prop1","Prop2"}), b);

this way the properties Prop1 and Prop2 are going to be ignored

Jul 27, 2012 at 4:36 PM

Is there anyway to do this without having your class inherit from LoopValueInjection?  I'm trying to inject objects that can't be modified to inherit from anything.

thanks-

 

Jul 27, 2012 at 4:58 PM

you could as well inherit ConventionInjection,

the default InjectFrom will inject everything with same name and type

Jun 21, 2013 at 5:10 AM
More syntax sugar:
public class IgnoreProperties : LoopValueInjection
{
    private readonly IEnumerable<string> _ignores;

    public IgnoreProperties(params string[] s)
    {
        _ignores = s;
    }

    protected override bool UseSourceProp(string sourcePropName)
    {
        return !_ignores.Contains(sourcePropName);
    }
}
usage:
  a.InjectFrom(new IgnoreProperties("Prop1","Prop2"), b);
Dec 23, 2013 at 5:16 PM
Hello,
I would like to do something like:
a.InjectFrom<UnflatLoopValueInjection>(new IgnoreProperties("Prop1", "Prop2"), b)
but does not work (does not ignore properties).
How to perform an unflattening operation (UnflatLoopValueInjection) while ignoring some properties?

Thanks,
//alessandro
Dec 23, 2013 at 6:07 PM
Edited Dec 23, 2013 at 6:08 PM
@alessandro you'll have to digg into the source code of UnflatLoopValueInjection and understand it
Mar 5, 2014 at 2:22 PM
Thanks for the code everyone. Very helpful. Especialy ZarShardan
Nov 5, 2014 at 8:24 PM
Edited Nov 5, 2014 at 8:26 PM
I propose a change to the function signature on
AllowSetValue(object value)

to
AllowSetValue(ValueInjectionContext context)

where ValueInjectionContext is:
public Type ObjectType { get; }
public object ObjectInstance { get; }
public string PropertyName { get; }
public object Value { get; }

I would like to annotate my model with [IgnoreInValueInjection]
For the stuff I would put in EntityBase to handle tenancy, optimistic concurrency, change tracking
Nov 5, 2014 at 8:49 PM
@leblanc have a look at ConventionInjection (newer)
Feb 25, 2015 at 4:55 PM
Is there a way to ignore specific properties when using:
InjectFrom<FastDeepCloneInjection>
I would like for these values in the copy to remain null/default.
Feb 25, 2015 at 5:49 PM
Edited Feb 25, 2015 at 5:50 PM
@mslissap you would have to edit FastDeepCloneInjection and make this possible, sort of the same way it was mentioned above,
here's another example:
public class IngnoreProps : ConventionInjection
{
    private readonly string[] _ignores;

    public IngnoreProps()
    {
    }

    public IngnoreProps(params string[] ignores)
    {
        _ignores = ignores;
    }

    protected override bool Match(ConventionInfo c)
    {
        return (_ignores == null || !_ignores.Contains(c.SourceProp.Name)) &&
               c.SourceProp.Name == c.TargetProp.Name
               && c.SourceProp.Type == c.TargetProp.Type;
    }
}
example of use:
object.InjectFrom(new IgnoreProps("Id","Other","Other","KeepGoing"), source);