ValueInjecter - рекурсивное отображение - PullRequest
2 голосов
/ 05 апреля 2011

Я довольно плохо знаком с автоматическим сопоставлением и даже новее с ValueInjecter.Извините, если это простой вопрос, но я нигде не могу найти ответ.

Как бы я сделал рекурсивное отображение?Например, вот мой текущий метод фабрики, который отображает Subject (из моей службы данных) в SubjectViewModel:

private SubjectViewModel createSubject(DataService.SubjectResult s) {
    SubjectViewModel result = new SubjectViewModel();
    result.SubjectName = s.SubjectName;
    result.id = s.id;

    foreach (DataService.SubjectResult sChild in s.Children)
        result.ChildSubjects.Add(createSubject(sChild));

    return result;
}

Я предполагаю, что это сложная ситуация для ValueInjecter,поэтому, если бы кто-то мог просто указать мне правильное направление, я был бы признателен за это!

Вот поддельный, но полный пример кода:

[TestClass]
public class UnitTest1 {

    [TestMethod]
    public void TestMethod1() {
        Subject S = new Subject() {
            id = 1,
            SubjectName = "S1", Children = { new Subject() { id = 2, SubjectName = "S1a" },
                                             new Subject() { id = 3, SubjectName = "S1b" }}
        };

        SubjectViewModel VM = new SubjectViewModel();
        VM.InjectFrom<CollectionToCollection>(S);

        Assert.AreEqual(2, VM.Children.Count);
    }
}


public class Subject {
    public Subject() {
        Children = new List<Subject>();
    }

    public string SubjectName { get; set; }
    public int id { get; set; }

    public List<Subject> Children { get; private set; }
}

public class SubjectViewModel {
    public SubjectViewModel() {
        Children = new List<SubjectViewModel>();
    }

    public string SubjectName { get; set; }
    public int id { get; set; }

    public List<SubjectViewModel> Children { get; set; }
}

public class CollectionToCollection : Omu.ValueInjecter.ConventionInjection {
    protected override bool Match(ConventionInfo c) {
        return c.SourceProp.Name == "Children";
    }

    protected override object SetValue(ConventionInfo c) {
        List<SubjectViewModel> result = new List<SubjectViewModel>();
        foreach (Subject S in (c.SourceProp.Value as IEnumerable<Subject>))
            result.Add(new SubjectViewModel());
        return result;
    }
}

РЕДАКТИРОВАТЬ - Iзнаю, что это наивный подход, который не рекурсивный.Прямо сейчас я просто пытаюсь получить это далеко без исключения

Прямо сейчас я получаю:

System.ArgumentException: объект типа 'System.Collections.Generic.List`1 [TestValueInjector.SubjectViewModel] 'невозможно преобразовать в тип' System.String '.

1 Ответ

2 голосов
/ 06 апреля 2011

причина, по которой вы получили эту ошибку, в том, что вы сопоставляли исходное свойство Children со всеми свойствами целевого объекта, поэтому SetValue вызывается для всех совпадений.

Что вам нужно было это:

protected override bool Match(ConventionInfo c)
{
   return c.SourceProp.Name == c.TargetProp.Name 
          && c.SourceProp.Name == "Children";
}
...