Я думаю, что вы делаете это слишком сложно, и просто нужно сделать что-то вроде этого.
this.name =
this.stock.getStockData(this.ticker, http)
.then( val => val.Name )
и
<h2>{{name.Name | async}}</h2>
Вероятно, самый простой способ - использовать DataBinder.Eval из System.Web.UI:
var foo = new Foo() { Bar = new Bar() { Value = "Value" } };
var value = DataBinder.Eval(foo, "Bar.Value");
В будущем (примерно в период времени 5.0) «компилятор как услуга» может это сделать. На самом деле, вы можете сделать многое из этого сейчас с помощью «моно» (см. CsharpRepl и Mono.CSharp ) - однако я думаю, что ему нужно будет знать намного больше о контексте для использования локальных переменных и т. д. в Evaluate
) - но в текущем предложении MS .NET для этого нет никакой поддержки.
На данный момент вам нужно что-то сделать как то, что делает большая часть кода привязки данных ... разделяет его на токены, такие как "." и использовать отражение. Строго говоря, код привязки фактически использует TypeDescriptor
/ PropertyDescriptor
, а не прямое отражение, но эффект тот же.
Несмотря на то, что это несколько тяжеловесный подход, вы можете использовать C # CodeDom для создания новой новой сборки, содержащей метод только с этой строкой кода.
Это намного сложнее- я признаю, что вы позволяете синтаксическому анализатору C # делать тяжелую работу, поэтому он должен быть в состоянии обрабатывать все, что вы ему бросаете, пока это действительный C #.
Если вы пойти по этому пути, вам также необходимо убедиться, что вы можете снова выгрузить созданную сборку, поэтому может потребоваться создание и выгрузка доменов приложений.
Я успешно реализовал и использовал вышеуказанный метод. С другой стороны, если вы можете использовать DynamicMethod , это будет намного легче. Однако я никогда не пробовал этот подход, поэтому не могу сказать, можете ли вы реализовать DynamicMethod '
Фактически, функция оценки выражений и обработчика правил Windows Workflow Foundation может делать такие вещи. См. Введение в механизм правил Windows Workflow Foundation .
Одна интересная особенность этих компонентов заключается в том, что они были разработаны таким образом, чтобы вы могли размещать компоненты времени разработки в своих собственных приложениях для разработки наборов правил и / или выражения, которые работают в контексте ваших собственных пользовательских классов. Например, вы скажете ему разработать выражение для «myObject», и он будет знать, что есть firstMember, у которого есть secondMember, у которого есть индексатор, дающий тип с текстовым свойством. Вы можете сохранить выражения и правила как XML и прочитать их во время выполнения, без необходимости использования конструктора во время выполнения.
В частности,
Насколько я знаю, такой встроенной функции Eval нет. Вам нужно будет пойти по пути Regex + Reflection. Я также думаю, что Visual Studio делает то же самое.
Вот что-то подобное, которое я использую для поиска динамически вложенных свойств ... вам нужно добавить логику для индексаторов ... и некоторые дополнительные проверки ... я ловлю нули / ошибки в моем методе вызова ...
public static object FindDottedProperty(this object input, string propertyName) { if (input == null) return null; if (string.IsNullOrEmpty(propertyName)) return null; Queue props = new Queue(propertyName.Split('.')); if (props.Count == 0) return null; //start with input object and roll out property stack from there. object ret = input; while (props.Count > 0) { var prop = props.Dequeue(); if (string.IsNullOrEmpty(prop)) return null; /*** ADD INDEXER LOGIC HERE ***/ //get the property's value based on the current named item ret = ret.GetType().GetProperty(prop).GetValue(ret, null); if (null.Equals(ret)) return null; } //return looked up value return ret; }
Вы всегда можете попробовать мою облегченную программу C # Eval. Он компилирует значительную часть языка C # в динамические методы. Полная информация о моем репозитории GitHub DavidWynne / CSharpEval