3

This is a counterpart to same question (but with AutoMapper). I use ValueInjecter and am interested if there is a solution.

Simplified code example:

// get a list of viewModels for the grid.
// NOTE: sort parameter is flattened property of the model (e.g. "CustomerInvoiceAmount" -> "Customer.Invoice.Amount"
// QUESTION: how do I get original property path so I can pass it to my repository for use with Dynamic LINQ?
public HttpResponseMessage Get(string sort)
{
    var models = _repo.GetAll(sort) // get a list of domain models
    var dto = _mapper.MapToDto(models); // get a list of view models that are flattened  via dto.InjectFrom<FlatLoopValueInjection>(models);

    var response = new HttpResponseMessage();
    response.CreateContent(vehicles);

    return response;
}
Community
  • 1
  • 1
zam6ak
  • 7,229
  • 11
  • 46
  • 84
  • look at the source code for flatloop and unflatloop injections, could be something that you need – Omu Jun 07 '12 at 16:23
  • also it would be helpful (for me to understand what you need), if you would show your input data and what result do you want to get from that input (try to make your questions clear, like questions on programming contests e.g. http://projecteuler.net/problem=12) – Omu Jun 07 '12 at 20:40
  • @Chuck Norris I thought that reference to same AutoMapper question would explain the goal, but I have made clarification in answer below. – zam6ak Jun 08 '12 at 16:16
  • ideally you would have had to ask: I have "FooBarName" and an object obj.Foo.Bar.Name, how do I get a string "Foo.Bar.Name" – Omu Jun 08 '12 at 16:37
  • @Chuck Norris While I would agree that example could have been more specific, I think the question is pretty clear..."FooBarName" is flattened property and "Foo.Bar.Name" is source property. Also I just took the title of the question for AutoMapper and changed it a bit. So it if wasn't clear its not my fault :) j/k – zam6ak Jun 08 '12 at 19:25
  • it always like that, everybody thinks that their question is very clear, but it isn't, from title I only get that you want to get the end property "Name", and in your question you have many unnecessary things like httpresponse, grid etc. and you link to a big question which I will never read, it's just too big – Omu Jun 08 '12 at 21:10

2 Answers2

1

Well, I was able to cobble something up but would really like some input from community (and perhaps from @Chuck Norris, who wrote ValueInjecter)...

So to restate the issue....

  • You have your flattened view model that is being used in your view.
  • View has a grid whose columns are properties of said view model.
  • When user clicks on the column a sort=columnName is passed to controller
  • So now you need to decode flattened property name into original object graph in order to pass it to your repository for server side sorting (e.g. using Dynamic Expression APi, Dynamic LINQ or such)...

So if a Company has property called President of type Employee, and Employee has property called HomeAddress of type Address, and Address has string property called Line1 then:

"President.HomeAddress.Line1" will be flattened to property called "PresidentHomeAddressLine1" on your view model.

In order to user server side sorting Dynamic Linq needs dotted property path, not flattened one. I need ValueInjecter to unflatten the flat property only! not entire class.

Here is what I came up with (relevant logic extracted from a method that does other things:

// type is type of your unflattened domain model.
// flatProperty is property name in your flattened view model
public string GetSortExpressionFor(Type type, string flatPropertyPath)
{
    if (type == null || String.IsNullOrWhiteSpace(flatPropertyPath))
    {
        return String.Empty;
    }

    // use ValueInjecter to find unflattened property
    var trails = TrailFinder.GetTrails(flatPropertyPath, type.GetInfos(), typesMatch => true).FirstOrDefault();
    var unflatPropertyPath = (trails != null && trails.Any()) ? String.Join(".", trails) : String.Empty;

    return unflatPropertyPath;
}



// sample usage     
var unflatPropertyPath = GetSortExpressionFor(typeof(Company), "PresidentHomeAddressLine1");
// unflatPropertyPath == "President.HomeAddress.Line1"
zam6ak
  • 7,229
  • 11
  • 46
  • 84
0

another way of doing this would be to use the TrailFinder

IEnumerable<IList<string>> GetTrails(string upn, IEnumerable<PropertyInfo> all, Func<Type, bool> f)

it's used by the UberFlatter like this:

var trails = TrailFinder.GetTrails(flatPropertyName, target.GetType().GetInfos(), f);

f Func check for the type of the end property to match a certain condition (probably in your case you could just return true)

Omu
  • 69,856
  • 92
  • 277
  • 407