Overriding Injections - do I have to remap everything?

May 9, 2012 at 3:56 PM

Great tool, thanks so much for your work.  I'm using ValueInjecter in an ASP.NET MVC4 site to do all sorts of mapping, and have run into an odd situation.  I have a nested domain object that I've written a ConventionInjection for, and have also overridden UnflatLoopValueInjectionM<string, string> to convert null values to string.Empty.  Now, when I inject my view model back to my nested domain object, the injection appears to be missing everything on the top-level domain object that isn't a string.  The domain object is "Client," which has a nested type "Person."  Here are my injection overrides:

public class NullStringUnflatLoopValueInjection : UnflatLoopValueInjection<string, string>
{
	protected override string SetValue(string sourceValue)
	{
		return sourceValue ?? string.Empty;
	}
}


public class ClientViewModelToPerson : ConventionInjection
{
	protected override bool Match(ConventionInfo c)
	{
		return c.SourceProp.Name == "FirstName" && c.SourceProp.Type == typeof (string) &&
			   c.TargetProp.Name == "Person" && c.TargetProp.Type == typeof (Data.Person);
	}

	protected override object SetValue(ConventionInfo c)
	{
		var source = c.Source.Value as ViewModels.Client.ClientViewModel;
		if (source == null)
			return null;
		var dest = c.TargetProp.Value as Data.Person;
		if (dest == null)
			return null;
		dest.FirstName = source.FirstName ?? string.Empty;
		dest.MiddleName = source.MiddleName ?? string.Empty;
		dest.LastName = source.LastName ?? string.Empty;
		dest.NickName = source.NickName ?? string.Empty;
		dest.IsFemale = source.IsFemale;
		dest.DateOfBirth = source.DateOfBirth;
		dest.Ssn = source.Ssn ?? string.Empty;
		dest.Phone1 = source.Phone1 ?? string.Empty;
		dest.Phone2 = source.Phone2 ?? string.Empty;
		dest.Phone3 = source.Phone3 ?? string.Empty;
		return dest;
	}
}

I've validated that the ClientViewModelToPerson injector is working correctly, but have found that the additional properties on the root Client object that are not strings do not get mapped.  Here's my controller code.

[HttpPost]
public ActionResult Edit(ClientViewModel clientViewModel)
{
    var client = _clientRepo.GetClient(viewModel.ClientId);
    client.InjectFrom<NullStringUnflatLoopValueInjection>(clientViewModel)
        .InjectFrom<ClientViewModelToPerson>(clientViewModel);
    _clientRepo.Save();
    return View(clientViewModel);
}

So my question is, do I have to override for all types or specify the Client object mappings in one of the injections?  Am I missing an injection in my controller?  I cannot add a default InjectFrom, as my model does not allow nulls on one of the Client string properties.  Hence the NullStringUnflatLoopValueInjection override.

Thanks very much for your help.

Coordinator
May 9, 2012 at 6:29 PM

by using the injection with <string,string> you constrained it to source and target type of string type, so it affects only those, you can do 2 calls like this:#

.lnjectFrom<UnflatLoop..>(source).InjectFrom<YourCustomStrStr>(source);

this way first will do all the generic work and second will affect only the strings

ConventionInjection doesn't do unflattening only unflatloop does 

May 9, 2012 at 7:31 PM

Ah, I see.  Unfortunately that defeats the purpose of the NullStringUnflatLoopValueInjection override.  I'm using Entity Framework 4.3.1, and all of my varchar columns are defined NOT NULL DEFAULT ''.  EF enforces the not null, and when I attempt to use the normal UnflatLoopValueInjection first, it throws an exception when a string value is null.  I will find another work-around.  Thanks for your response!

Coordinator
May 9, 2012 at 8:21 PM

just grab the code of the unflatloopinjection and do it as you need

May 9, 2012 at 9:25 PM

Done and done, works like a charm.  Thanks!