Поделиться через


Пошаговое руководство. Подключение основного приложения к созданному обработчику директив

Вы можете написать собственный узел, обрабатывающий текстовые шаблоны. Базовый пользовательский узел демонстрируется в пошаговом руководстве. Создание узла пользовательского текстового шаблона. Этот узел можно расширить для добавления таких функций, как создание нескольких выходных файлов.

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

Примечание.

В этом пошаговом руководстве показано, как создать пользовательский узел шаблона текста. Сначала выполните это пошаговое руководство.

В этом пошаговом руководстве рассматриваются следующие задачи:

  • Использование средств языка для конкретного домена для создания обработчика директив, основанного на модели домена.

  • Подключение узла пользовательского текстового шаблона в созданный обработчик директив.

  • Тестирование пользовательского узла с помощью созданного обработчика директив.

Необходимые компоненты

Для определения доменного языка необходимо установить следующие компоненты.

Компонент Установить связь
Visual Studio http://go.microsoft.com/fwlink/?LinkId=185579
SDK для Visual Studio http://go.microsoft.com/fwlink/?LinkId=185580
Пакет SDK для визуализации и моделирования в Visual Studio

Примечание.

Компонент Text Template Transformation (Преобразование текстовых шаблонов) автоматически устанавливается как часть рабочей нагрузки разработки расширений Visual Studio. Его также можно установить на вкладке Отдельные компоненты Visual Studio Installer в категории Пакеты SDK, библиотеки и платформы. Установите компонент Пакет SDK для моделирования со вкладки Отдельные компоненты.

Кроме того, необходимо создать преобразование пользовательского текстового шаблона, созданное в пошаговом руководстве. Создание узла пользовательского текстового шаблона.

Использование языковых средств для конкретного домена для создания обработчика директив

В этом пошаговом руководстве вы используете мастер конструктора языков для конкретного домена, чтобы создать язык для конкретного домена для решения DSLMinimalTest.

  1. Создайте решение для конкретного домена, которое имеет следующие характеристики:

    • Имя: DSLMinimalTest

    • Шаблон решения: минимальный язык

    • Расширение файла: min

    • Название компании: Fabrikam

    Дополнительные сведения о создании решения для конкретного домена см. в статье "Практическое руководство. Создание решения для конкретного домена".

  2. В меню Сборка выберите Построить решение.

    Важно!

    На этом шаге создается обработчик директив и добавляется ключ для него в реестре.

  3. В меню Отладка выберите пункт Начать отладку.

    Откроется второй экземпляр Visual Studio.

  4. В экспериментальной сборке в Обозреватель решений дважды щелкните файл sample.min.

    Файл открывается в конструкторе. Обратите внимание, что модель содержит два элемента: ExampleElement1 и ExampleElement2, а также связь между ними.

  5. Закройте второй экземпляр Visual Studio.

  6. Сохраните решение, а затем закройте конструктор языков для конкретного домена.

Подключение узла пользовательского текстового шаблона обработчику директив

После создания обработчика директив подключите обработчик директив и узел пользовательского текстового шаблона, созданный в пошаговом руководстве. Создание узла пользовательского текстового шаблона.

  1. Откройте решение CustomHost.

  2. В меню Проект выберите пункт Добавить ссылку.

    Откроется диалоговое окно "Добавить ссылку" со вкладкой .NET .

  3. Добавьте следующие ссылки:

    • Microsoft.VisualStudio.Modeling.Sdk.11.0

    • Microsoft.VisualStudio.Modeling.Sdk.Diagrams.11.0

    • Microsoft.VisualStudio.TextTemplating.11.0

    • Microsoft.VisualStudio.TextTemplating.Interfaces.11.0

    • Microsoft.VisualStudio.TextTemplating.Modeling.11.0

    • Microsoft.VisualStudio.TextTemplating.VSHost.11.0

  4. В верхней части Program.cs или Module1.vb добавьте следующую строку кода:

    using Microsoft.Win32;
    
  5. Найдите код для свойства StandardAssemblyReferencesи замените его следующим кодом:

    Примечание.

    На этом шаге вы добавите ссылки на сборки, необходимые созданному обработчику директив, который будет поддерживать ваш узел.

    //the host can provide standard assembly references
    //the engine will use these references when compiling and
    //executing the generated transformation class
    //--------------------------------------------------------------
    public IList<string> StandardAssemblyReferences
    {
        get
        {
            return new string[]
            {
                //if this host searches standard paths and the GAC
                //we can specify the assembly name like this:
                //"System"
                //since this host only resolves assemblies from the
                //fully qualified path and name of the assembly
                //this is a quick way to get the code to give us the
                //fully qualified path and name of the System assembly
                //---------------------------------------------------------
                typeof(System.Uri).Assembly.Location,
                            typeof(System.Uri).Assembly.Location,
                typeof(Microsoft.VisualStudio.Modeling.ModelElement).Assembly.Location,
                typeof(Microsoft.VisualStudio.Modeling.Diagrams.BinaryLinkShape).Assembly.Location,
                typeof(Microsoft.VisualStudio.TextTemplating.VSHost.ITextTemplating).Assembly.Location,
                typeof(Microsoft.VisualStudio.TextTemplating.VSHost.ModelingTextTransformation).Assembly.Location
    
            };
        }
    }
    
  6. Найдите код функции ResolveDirectiveProcessorи замените его следующим кодом:

    Важно!

    Этот код содержит жестко закодированные ссылки на имя созданного обработчика директив, к которому требуется подключиться. Вы можете легко сделать это более общим, в этом случае он ищет все процессоры директив, перечисленные в реестре, и пытается найти совпадение. В этом случае узел будет работать с любым созданным обработчиком директив.

    //the engine calls this method based on the directives the user has
            //specified it in the text template
            //this method can be called 0, 1, or more times
            //---------------------------------------------------------------------
            public Type ResolveDirectiveProcessor(string processorName)
            {
                //check the processor name, and if it is the name of the processor the
                //host wants to support, return the type of the processor
                //---------------------------------------------------------------------
                if (string.Compare(processorName, "DSLMinimalTestDirectiveProcessor", StringComparison.InvariantCultureIgnoreCase) == 0)
                {
                    try
                    {
                        string keyName = @"Software\Microsoft\VisualStudio\10.0Exp_Config\TextTemplating\DirectiveProcessors\DSLMinimalTestDirectiveProcessor";
                        using (RegistryKey specificKey = Registry.CurrentUser.OpenSubKey(keyName))
                        {
                            if (specificKey != null)
                            {
                                List<string> names = new List<String>(specificKey.GetValueNames());
                                string classValue = specificKey.GetValue("Class") as string;
                                if (!string.IsNullOrEmpty(classValue))
                                {
                                    string loadValue = string.Empty;
                                    System.Reflection.Assembly processorAssembly = null;
                                    if (names.Contains("Assembly"))
                                    {
                                        loadValue = specificKey.GetValue("Assembly") as string;
                                        if (!string.IsNullOrEmpty(loadValue))
                                        {
                                            //the assembly must be installed in the GAC
                                            processorAssembly = System.Reflection.Assembly.Load(loadValue);
                                        }
                                    }
                                    else if (names.Contains("CodeBase"))
                                    {
                                        loadValue = specificKey.GetValue("CodeBase") as string;
                                        if (!string.IsNullOrEmpty(loadValue))
                                        {
                                            //loading local assembly
                                            processorAssembly = System.Reflection.Assembly.LoadFrom(loadValue);
                                        }
                                    }
                                    if (processorAssembly == null)
                                    {
                                        throw new Exception("Directive Processor not found");
                                    }
                                    Type processorType = processorAssembly.GetType(classValue);
                                    if (processorType == null)
                                    {
                                        throw new Exception("Directive Processor not found");
                                    }
                                    return processorType;
                                }
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        //if the directive processor can not be found, throw an error
                        throw new Exception("Directive Processor not found");
                    }
                }
    
                //if the directive processor is not one this host wants to support
                throw new Exception("Directive Processor not supported");
            }
    
  7. В меню File (Файл) выберите команду Save All (Сохранить все).

  8. В меню Сборка выберите Построить решение.

Тестирование пользовательского узла с помощью обработчика директив

Чтобы протестировать узел пользовательского текстового шаблона, сначала необходимо написать текстовый шаблон, вызывающий созданный обработчик директив. Затем запустите пользовательский узел, передайте в него имя текстового шаблона и убедитесь, что директива обработана правильно.

Создание текстового шаблона для тестирования пользовательского узла

  1. Создайте текстовый файл и назовите его TestTemplateWithDP.tt. Для создания файла можно использовать любой текстовый редактор, например Блокнот.

  2. Добавьте в текстовый файл следующий текст:

    Примечание.

    Язык программирования текстового шаблона не должен соответствовать языку пользовательского узла.

    Text Template Host Test
    
    <#@ template debug="true" inherits="Microsoft.VisualStudio.TextTemplating.VSHost.ModelingTextTransformation" #>
    <# //this is the call to the examplemodel directive in the generated directive processor #>
    <#@ DSLMinimalTest processor="DSLMinimalTestDirectiveProcessor" requires="fileName='<Your Path>\Sample.min'" provides="ExampleModel=ExampleModel" #>
    <# //uncomment this line to test that the host allows the engine to set the extension #>
    <# //@ output extension=".htm" #>
    
    <# //uncomment this line if you want to see the generated transformation class #>
    <# //System.Diagnostics.Debugger.Break(); #>
    <# //this code uses the results of the examplemodel directive #>
    <#
        foreach ( ExampleElement box in this.ExampleModel.Elements )
        {
            WriteLine("Box: {0}", box.Name);
    
            foreach (ExampleElement linkedTo in box.Targets)
            {
                WriteLine("Linked to: {0}", linkedTo.Name);
            }
    
            foreach (ExampleElement linkedFrom in box.Sources)
            {
                WriteLine("Linked from: {0}", linkedFrom.Name);
            }
    
            WriteLine("");
        }
    #>
    
  3. В коде замените <YOUR PATH> путем файла Sample.min из языка разработки, созданного в первой процедуре.

  4. Сохранить и закрыть файл.

Тестирование пользовательского узла

  1. Откройте окно командной строки.

  2. Введите путь к исполняемому файлу пользовательского ведущего приложения, но пока не нажимайте клавишу ВВОД.

    Например, введите:

    <YOUR PATH>CustomHost\bin\Debug\CustomHost.exe

    Примечание.

    Вместо ввода адреса можно перейти к файлу CustomHost.exe в Windows Обозреватель, а затем перетащите файл в окно командной строки.

  3. Введите пробел.

  4. Введите путь к файлу текстового шаблона и нажмите клавишу ВВОД.

    Например, введите:

    <YOUR PATH>TestTemplateWithDP.txt

    Примечание.

    Вместо ввода адреса можно перейти к файлу TestTemplateWithDP.txt в Windows Обозреватель, а затем перетащите файл в окно командной строки.

    Настраиваемое приложение узла запускает и запускает процесс преобразования текстового шаблона.

  5. В Windows Обозреватель перейдите к папке, содержащей файл TestTemplateWithDP.txt.

    Папка также содержит файл TestTemplateWithDP1.txt.

  6. Откройте этот файл, чтобы увидеть результаты преобразования текстового шаблона.

    Результаты созданных текстовых выходных данных отображаются и должны выглядеть следующим образом:

    Text Template Host Test
    
    Box: ExampleElement1
    Linked to: ExampleElement2
    
    Box: ExampleElement2
    Linked from: ExampleElement1