Сопоставление узла umbraco со строго типизированным объектом

Я работаю с Umbraco 4.7.1 и пытаюсь сопоставить узлы содержимого с некоторыми автоматически сгенерированными строго типизированными объектами. Я пытался использовать как valueinjecter, так и automapper, но OOTB ни один из них не отображает мои свойства. Я предполагаю, что это потому, что все свойства на узле Umbraco (документ cms) извлекаются следующим образом:

node.GetProperty("propertyName").Value;

И мои строго типизированные объекты имеют формат MyObject.PropertyName. Итак, как мне сопоставить свойство узла, которое извлекается с помощью метода и строки, начинающейся с символа нижнего регистра, со свойством MyObject, где свойство начинается с символа верхнего регистра?

ОБНОВЛЕНИЕ Мне удалось создать следующий код, который сопоставляет узел umbraco, как предполагалось, покопавшись в исходном коде Umbraco в поисках вдохновения о том, как преобразовать строковые свойства в строго типизированные свойства:

    public class UmbracoInjection : SmartConventionInjection
{
    protected override bool Match(SmartConventionInfo c)
    {
        return c.SourceProp.Name == c.TargetProp.Name;
    }

    protected override void Inject(object source, object target)
    {
        if (source != null && target != null)
        {

            Node node = source as Node;

            var props = target.GetProps();
            var properties = node.Properties;

            for (int i = 0; i < props.Count; i++)
            {
                var targetProperty = props[i];
                var sourceProperty = properties[targetProperty.Name];
                if (sourceProperty != null && !string.IsNullOrWhiteSpace(sourceProperty.Value))
                {
                    var value = sourceProperty.Value;
                    var type = targetProperty.PropertyType;
                    if (targetProperty.PropertyType.IsValueType && targetProperty.PropertyType.GetGenericArguments().Length > 0 && typeof(Nullable<>).IsAssignableFrom(targetProperty.PropertyType.GetGenericTypeDefinition()))
                    {
                        type = type.GetGenericArguments()[0];
                    }
                    targetProperty.SetValue(target, Convert.ChangeType(value, type));
                }
            }
        }
    }
}

Как видите, я использую SmartConventionInjection для ускорения работы. Для отображения примерно 16000 объектов по-прежнему требуется примерно 20 секунд. Можно ли это сделать еще быстрее?

Благодарность

Томас


person ThomasD    schedule 18.04.2012    source источник


Ответы (1)


с ValueInjecter вы бы сделали что-то вроде этого:

public class Um : ValueInjection
{
    protected override void Inject(object source, object target)
    {
        var node = target as Node;
        var props = source.GetProps();
        for (int i = 0; i < props.Count; i++)
        {
            var prop = props[i];
            target.GetProperty(prop.Name).Value;

        }
    }
}
person Omu    schedule 18.04.2012
comment
благодаря. Когда я пытаюсь установить значение для цели, я получаю сообщение об ошибке: Объект типа «System.String» не может быть преобразован в тип «System.Nullable`1 [System.Int32]. Любая помощь приветствуется. Спасибо - person ThomasD; 18.04.2012
comment
Я не публиковал весь код, но в основном сообщение предполагает, что вы пытаетесь установить строковое свойство с помощью int? значение, вы можете видеть, что я сопоставляю свойства только по имени, выполнив target.GetProperty(prop.Name), но я не проверяю тип или что-то еще, поэтому вам нужно сделать это, если у вас есть одинаковые реквизиты имя, но разные типы - person Omu; 18.04.2012
comment
Привет. Имена свойств уникальны, и все значения на исходном узле хранятся в виде строк. Как привести исходное свойство к правильному целевому типу свойства? Я новичок во всех этих размышлениях, так что извините за то, что может быть простым вопросом - person ThomasD; 18.04.2012
comment
это довольно просто, вы должны разобраться с intellisense, я не разбираюсь в umbraco, но для обычных объектов вы можете сделать это var sourceValue = prop.GetValue(source); - person Omu; 18.04.2012
comment
Спасибо. Я не мог заставить его работать, хотя. Дело в том, что все значения Umbraco являются строками. Но автоматически сгенерированные объекты, свойства которых я пытаюсь сопоставить, относятся к разным типам. Например. У меня может быть такое свойство, как Node.Price = 54, а в строго типизированном объекте Object.Price — это int. Можно ли вывести этот тип из строго типизированного объекта, а затем привести строковое значение из узла, прежде чем присваивать его строго типизированному объекту? Спасибо - person ThomasD; 18.04.2012
comment
вы могли бы сделать что-то вроде большого переключателя или, если еще if (prop.PropertyType == typeof(int)) strval = sourceValue.ToString() else if ... - person Omu; 18.04.2012
comment
Мне удалось передать свойства, посмотрев исходный код umbraco. Я обновил вопрос выше, потому что хотел бы улучшить производительность. Вы можете помочь ? Спасибо - person ThomasD; 20.04.2012
comment
Спасибо. Я попытался найти документацию для HyperDescriptor (согласно потоку здесь: stackoverflow.com/questions/2786761/automapper-recursive), но я не могу найти его на codeplex. Кстати, спасибо за впечатляющую поддержку! - person ThomasD; 20.04.2012
comment
посмотрите здесь valueinjecter.codeplex.com/SourceControl/changeset/view/ в методе Start() - person Omu; 20.04.2012
comment
Спасибо. Мне удалось увеличить производительность в 4 раза на моем dev-box. В продакшене еще не проверял - person ThomasD; 25.04.2012