Занятия по шаблону бритвенного двигателя - PullRequest
24 голосов
/ 26 февраля 2011

Возможно ли создавать классы внутри шаблона?Что-то вроде ...

@{
    public class MyClass {
        public MyClass() {
            Three = new List<string>();
        }

        public string One { get; set; }
        public int Two { get; set; }
        public List<string> Three { get; set; }
    }
}

В настоящее время я получаю "Невозможно скомпилировать шаблон. Проверьте список ошибок для деталей."когда я пытаюсь сделать это.Я хотел бы взять содержимое XML и использовать XmlSerializer для создания экземпляра MyClass в шаблоне.Я не могу выполнить десериализацию заранее и вставить ее в модель, потому что классы могут отличаться в зависимости от шаблона.

Ответы [ 3 ]

86 голосов
/ 28 октября 2013

Да, это вполне возможно. Используйте ключевое слово @functions:

@functions {
    public class MyClass {
        public MyClass() {
            Three = new List<string>();
        }

        public string One { get; set; }
        public int Two { get; set; }
        public List<string> Three { get; set; }
    }
}
5 голосов
/ 27 февраля 2011

Я выложу свой ответ от обсуждения CodePlex здесь:

Я не уверен, что это возможно в настоящее время. Когда вы используете кодовые блоки (@ {}), вы на самом деле пишете код внутри метода, например, Ваш код выше будет делать что-то вроде:

public void Execute()
{
    this.Clear();
    public class MyClass {
        public MyClass() {
            Three = new List<string>();
        }

        public string One { get; set; }
        public int Two { get; set; }
        public List<string> Three { get; set;}
    }
}

... что, конечно, не является допустимым C #. Другая проблема, с которой вы столкнетесь, заключается в том, что для использования сериализации / десериализации xml тип должен быть известен, но если вы определяете свой тип в самом шаблоне, как вы можете десериализовать его в первую очередь?

То, что вы могли бы сделать, это использовать собственный базовый шаблон:

public class CustomTemplateBase<T> : TemplateBase<T>
{
    public dynamic Instance { get; set; }

    public dynamic CreateInstance(string typeName)
    {
        Type type = Type.GetType(typeName);

        // You'd to your deserialisation here, I'm going to
        // just cheat and return a new instance.
        return Activator.CreateInstance(type);
    }
}

Используя динамическое свойство и динамический тип возврата, мы определили метод, который позволит нам создавать экземпляр (посредством активации или десериализации и т. Д.) И вызывать для него доступ к элементу. Чтобы использовать это в шаблоне, вы можете сделать:

@{
  Instance = CreateInstance("ConsoleApplication1.MyClass, ConsoleApplication1");
  Instance.One = "Hello World";
}
<h1>@Instance.One</h1>

Где "MyClass" определен где-то в моем приложении. Важно то, что я создаю экземпляр для каждого шаблона.

3 голосов
/ 27 февраля 2011

Я бы предложил использовать определенный класс ViewModel, который мог бы иметь динамическое свойство (ExpandoObject), позволяющее вам заполнять его любой пользовательской структурой данных по мере необходимости, в то же время общаясь строго типизированным для всего, что может понадобиться вашему представлению.

Это также позволяет отделить ваши модели представлений от самих представлений, что является хорошей практикой (html и код не слишком хорошо сочетаются в тех случаях, когда важна читаемость).

...