mapping identical nested classes?

Jan 6, 2011 at 5:53 PM

Hello O.

I would like to map all properties like so:

 

class1 {
     child { childproperty1 }
     classproperty1
}

class2 {
     child { childproperty1 }
     classproperty1
}

 

class1.InjectFrom(class2);

this will map classproperty1 but not child property1

I then thought this might work :

class1.InjectFrom<LoopValueInjection>(class2);

but this just all out fails, i suspect it is only to be inherited from, not to be used like the flat and unflat loops.

Any suggestions?

 

Thanks, Kohan.

Coordinator
Jan 6, 2011 at 8:27 PM

I don't really get what you need, and what's your problem, and I don't see any difference between class1 and 2, could you please write exact c# instead of pseudo code

Jan 7, 2011 at 2:26 PM

public class ClientViewModel
{
   public int Id { get; set; }
   public string Name { get; set; }
}

public class ProgrammeClientViewModel
{
    public int Id { get; set; }
    public bool IsActive { get; set; }
    public ClientViewModel Client { get; set; }
}

---------

public class Client
{
   public int Id { get; set; }
   public string Name { get; set; }
}

public class ProgrammeClient
{
    public int Id { get; set; }
    public bool IsActive { get; set; }
    public IClient Client { get; set; }
}

I would like to do:

        private void MapModelToEntity(IProgrammeClient programmeClient, ProgrammeClientViewModel model)
        {
programmeClient.InjectFrom(model);
}

And have properties on programmeClient and programmeClient.Client injected from model (ProgrammeClientViewModel).

Sorry this is the best that i can do as the code i am working on is not suitable to post in it's entirety.

 

Coordinator
Jan 7, 2011 at 4:21 PM

the .InjectFrom is going to do just the Id and the IsActive because they are of the same name and type

the Client props are of different types so you need another injection for them, something like:

public class ClientVMtoEntity : LoopValueInjection
{
protected override bool TypesMatch(Type sourceType, Type targetType)
{
return sourceType == typeof(ClientViewModel)
&& targetType == typeof(Client);// if you use interfaces or abstract classes you could use something else instead of ==
}

protected override object SetValue(object v)
{// v is of type ClientViewModel
return new Client().InjectFrom(v);
}
}
Jan 7, 2011 at 4:30 PM

Is there anything i can override so that it ignores type matching for any objects an only concerns itself with the properties themselves?

Coordinator
Jan 7, 2011 at 4:35 PM

if you want to match them only by name you could

protected override bool TypesMatch(Type sourceType, Type targetType)
{
return true;
}

but you are for sure going to have problems with type casting
Jan 7, 2011 at 5:05 PM
Edited Jan 7, 2011 at 5:11 PM
o wrote:

the .InjectFrom is going to do just the Id and the IsActive because they are of the same name and type

the Client props are of different types so you need another injection for them, something like:

public class ClientVMtoEntity : LoopValueInjection
{
protected override bool TypesMatch(Type sourceType, Type targetType)
{
return sourceType == typeof(ClientViewModel)
&& targetType == typeof(Client);// if you use interfaces or abstract classes you could use something else instead of ==
}

protected override object SetValue(object v)
{// v is of type ClientViewModel
return new Client().InjectFrom(v);
}
}

Correct, i am getting a type mismatch exception.

In the example above instead of creating a new instance of Client, could you instead use the existing instance from ProgrammeClient to get round this?

or even better...

If TypesMatch is false but the names match then detect the sourcetype and create a new one of them to inject into.

Coordinator
Jan 7, 2011 at 5:23 PM

if type TypesMatch returns false SetValue will not execute, and this is good because you don't want to something like:

foo.InjectFrom<MyInj>(bar)

where

foo.Prop1 is String and bar.Prop1 is Class1

that's why doing just return true; for TypesMatch generally is a bad idea

as for the Loopinjection that I wrote above probably I did something wrong I don't know all your code,

probably instead of

new Client().InjectFrom(v) you need new ClientViewModel().InjectFrom(v), I'm not sure
Jan 10, 2011 at 10:37 AM

Is there any way of making this more generic?

Would it be possible to get target type into SetValue?

protected override bool TypesMatch(Type sourceType, Type targetType)
{
return (sourceType == targetType) || sourceType.IsClass;
}

protected override object SetValue(object v)
{
if (v.GetType().IsClass)
return new TargetType.InjectFrom(v);

return v;
}
Coordinator
Jan 10, 2011 at 12:46 PM

yes,

instead of new TargetType

do:

Activator.CreateInstance(TargetPropertyType .... something like that

Jan 10, 2011 at 2:09 PM
Edited Jan 10, 2011 at 2:18 PM

What would you recommend is the best way to get targetType from TypesMatch() into SetValue()?


Apologies for all these questions :)

Coordinator
Jan 10, 2011 at 7:29 PM

go in the SetValue() method, hit Ctrl+Space start typing TargetProp... SourceProp... , you will se both of them ;)