Динамическое создание и компиляция исходного кода — .NET Framework
Twitter LinkedIn Facebook Адрес электронной почты
- Статья
- Чтение занимает 2 мин
Платформа . NET включает механизм, называемый объектной моделью документов кода (CodeDOM), который позволяет разработчикам программ, которые выдают исходный код, создавать исходный код на нескольких языках программирования во время выполнения на основе одной модели, представляющей код для отрисовки.
Для представления исходного кода элементы CodeDOM связываются друг с другом, образуя структуру данных, известную как граф CodeDOM, которая моделирует структуру некоторого исходного кода.
Пространство имен System.CodeDom определяет типы, с помощью которых логическая структура исходного кода может быть представлена независимо от конкретного языка программирования. Пространство имен System.CodeDom.Compiler определяет типы, используемые для формирования исходного кода на основе графов CodeDOM и управления компиляцией исходного кода на поддерживаемых языках. Набор поддерживаемых языков может быть расширен разработчиками или поставщиками компиляторов.
Независимое от языка моделирование исходного кода может быть полезно, если программа должна создавать исходный код для модели программы на нескольких языках или если конечный язык заранее не определен. Например, некоторые конструкторы используют модель CodeDOM в качестве интерфейса абстракции от языка для получения исходного кода на требуемом языке программирования, если имеется поддержка CodeDOM для этого языка.
Платформа .NET включает генераторы кода и компиляторы кода для CSharpCodeProvider, JScriptCodeProviderи VBCodeProvider.
Содержание раздела
Использование CodeDOM
Описываются общие случаи применения, а также демонстрируется создание простого графа объектов с использованием CodeDOM.
Создание исходного кода и компиляция программы из графа CodeDOM
Описание способов формирования исходного кода и его компиляции внешним компилятором с использованием классов, определенных в пространстве имен
.Практическое руководство. Создание XML-файла документации с использованием CodeDOM
Описание использования CodeDOM для формирования кода с комментариями к XML-документации и компиляции сформированного кода для создания XML-документации.
Практическое руководство. Создание класса с помощью CodeDOM
Описание использования CodeDOM для создания класса, содержащего поля, свойства, метод, конструктор и точку входа.
Справочник
System.CodeDom
Определяет элементы, представляющие элементы кода на языках программирования, предназначенных для среды CLR.
System.CodeDom.Compiler
Определяет интерфейсы для формирования и компиляции кода во время выполнения.
- Краткий справочник по CodeDOM — здесь разработчики могут быстро найти элементы CodeDOM, представляющие элементы исходного кода.
Динамическое создание компонентов в Angular (Перевод) | by Alexander Bukhtatyy
Оригинал: https://netbasal.com/dynamically-creating-components-with-angular-a7346f4a982d
В данной статье, мы изучим как динамический создать компонент в Angular.
Для начала нам нужен компонент.
Для простоты мы собираемся использовтаь простой компонент alert
который будет принимать как Input
тип алерта.
Итак, если задуматьяс то каждый компонент влется DOM элементом, так что когда вам нужно добавтиь елемент, вам нужно место куда положить его.
В Angular, такое место называется container.
В my-app
компоненте, мы создадим шаблонный элемент. Мы так же пометим его хэш символом (#)для обьявления ссылки под названием alertContainer
. template
элемнет является тем самым местом, или в мире Angular , container.
Замечание: Контейнером может быть любой DOM-элемент или компонент.
Теперь нам нужно достать ссылку на наш контейнер в my-app
компоненте.
Мы можем достать ссылку на контейнер использу ViewChild
декоратор который так же принимает локальную переменную в качестве параметра.
По умолчанию значение декоратораViewChild
— это экземпляр компонента или DOM-элемент, но в нашем случае нам нужно достать элемент как ViewContainerRef
.
Как следует из названия, ViewContainerRef
является ссылкой на контейнер. ViewContainerRef
хранит ссылку на шаблонный елемент (наш контейнер) и так же предоставляет API для создания компонентов.
Создадим 2 кнопки которые помогут нам создать alert
компонент.
Прежде чем мы вызовем createComponent()
метод, нам нужно добавиль еще один сервис.
ComponentFactoryResolver
сервис предоставлет один основной метод — resolveComponentFactory
.
resolveComponentFactory()
метод берет компонент и возвращает ComponentFactory
.
Вы можете думать о ComponentFactory
как о обьекте который знает как создавать компоненты.
Как вы можете наблюдать ComponentFactory
предоставляет create()
метод который будет использован внутри контейнера (ViewContainerRef ).
Теперь послендний шаг.
Давайте обьясню что происходит шаг за шагом.
Каждый раз когда нам нужно создать компонент нам нужно удалить предыдущее представление, иначе компоненты будут добавляться в контейнер. не обязательно если вам нужно добавить несколько компонентов.
Метод resolveComponentFactory()
принимает компонент и возвращает фабрику(рецепт) для создания этого компонента.
Мы вызываем createComponent()
метод и передаем ему рецепт. Внутри этого метода будет вызван метод create()
из фабрики и будет добавлен компонент после нашего контейнера.
Теперь мы имеем ссылку на наш новый компонент, и мы может устрановить через Input
свойство типа.
Вы так же можете подписаться на Output
компонента как продемонстрированно ниже:
И не забудьте уничтожить компонент:
Последним шагом будет — добавление вашего динамического компонента в entryComponents секцию вашего модуля:
Динамическое создание бинов в Spring
спросил
Изменено 11 лет, 3 месяца назад
Просмотрено 7к раз
Есть ли способ весной, когда мы можем прочитать поля bean-компонента из таблицы БД и создать полный класс bean-компонента — с геттерами и сеттерами при запуске сервера????
Мне нужно это, чтобы сделать мое приложение полностью настраиваемым. .. как если бы мне нужно было добавить новое поле в будущем, все, что мне потребуется, это добавить поле в базу данных, и мне будут доступны установщики и геттеры bean-компонентов. .
Спасибо
- весна
- динамический
- javabeans
- создание
1
Вы можете попробовать подходы для динамической регистрации bean-компонентов. Вы можете использовать BeanDefinitionBuilder для этой цели. См. образец здесь. Но, как говорит @Darren, не стоит создавать бин через поиск в БД.
0
1: Улучшите свою скорость принятия
2: Вы можете извлечь выгоду из чего-то вроде подхода ORM (Hibernate или JPA). Еще один немного отличающийся подход, который может вам подойти, — это шаблон Active Record, реализованный, например, в ActiveJDBC.
Spring сам по себе не предлагает ничего подобного тому, что вам нужно, но использование spring-jpa вместе с Hibernate может немного приблизить вас к вашей цели.
Если, OTOH, вам нужен автоматически сгенерированный код, вы также можете посмотреть на что-то вроде Spring-Roo 9.0005Возможно, вы захотите еще немного подумать об этом. Даже если вы сделали свои поля полностью настраиваемыми, вам все равно придется писать код для доступа к ним. И, учитывая, что вам все равно придется писать код, лучше оставить все в коде. Так намного проще.
2
Зарегистрируйтесь или войдите в систему
Зарегистрируйтесь с помощью Google
Зарегистрироваться через Facebook
Зарегистрируйтесь, используя электронную почту и пароль
Опубликовать как гость
Электронная почта
Требуется, но никогда не отображается
Опубликовать как гость
Электронная почта
Требуется, но не отображается
типов — Динамическое создание типов и имена для встроенных типов — Документация по Python 3.
11.3Исходный код: Lib/types.py
Этот модуль определяет служебные функции, помогающие в динамическом создании новые виды.
Он также определяет имена для некоторых типов объектов, которые используются стандартом
Интерпретатор Python, но не представленный как встроенный, например вместо
или стр
ар.
Наконец, он предоставляет некоторые дополнительные служебные классы и функции, связанные с типами. которые недостаточно фундаментальны, чтобы быть встроенными.
Создание динамического типа
- types.new_class( name , bases=() , kwds=None , exec_body=None )
Динамически создает объект класса, используя соответствующий метакласс.
Первые три аргумента — это компоненты, составляющие класс заголовок определения: имя класса, базовые классы (по порядку), аргументы ключевого слова (например,
метакласс
).Аргумент exec_body является обратным вызовом, который используется для заполнения только что созданное пространство имен классов. Он должен принимать пространство имен класса в качестве единственного аргумента и обновить пространство имен непосредственно с помощью класса содержание. Если обратный вызов не предоставляется, он имеет тот же эффект, что и передача в
лямбда-выражения: Нет
.
- types.prepare_class( name , bases=() , kwds=None )
Вычисляет соответствующий метакласс и создает пространство имен класса.
Аргументы — это компоненты, составляющие заголовок определения класса: имя класса, базовые классы (по порядку) и ключевые аргументы (например, метакласс
Возвращаемое значение представляет собой 3-кортеж:
метакласс, пространство имен, kwds
метакласс является подходящим метаклассом, пространство имен является подготовленное пространство имен классов и kwds это обновленная копия переданного в аргументе kwds с удалением любой записи
«метакласс»
. Если нет kwds передается аргумент, это будет пустой диктофон.Новое в версии 3.3.
Изменено в версии 3.6: значение по умолчанию для элемента пространства имен
__prepare__
.
См. также
- Метаклассы
Полная информация о процессе создания классов, поддерживаемом этими функциями
- PEP 3115 — Метаклассы в Python 3000
Добавлен хук пространства имен
__prepare__
- типы.resolve_bases ( баз )
Динамическое разрешение записей MRO, как указано в PEP 560 .
Эта функция ищет элементы в оснований , которые не являются экземплярами
введите
и возвращает кортеж, в котором каждый такой объект, метод__mro_entries__
заменяется на распакованный результат вызов этого метода.типа
, или у него нет метода__mro_entries__
, то он включен в возвращаемый кортеж без изменений.Новое в версии 3.7.
См. также
PEP 560 — Основная поддержка модуля ввода и универсальных типов
Стандартные типы интерпретаторов
Этот модуль предоставляет имена для многих типов, необходимых для
реализовать интерпретатор Python. Он намеренно избегает включения некоторых из
типы, которые возникают только случайно во время обработки, такие как листитератор типа
.
Типичное использование этих имен для isinstance()
или issubclass()
проверок.
Если вы создаете экземпляр любого из этих типов, обратите внимание, что сигнатуры могут различаться в разных версиях Python.
Стандартные имена определены для следующих типов:
- типы .NoneType
Тип
Нет
.Новое в версии 3.10.
- типы. Тип функции
- типы.LambdaType
Тип пользовательских функций и функций, созданных
лямбда
выражений.Вызывает событие аудита
function.__new__
с аргументом, код
.Событие аудита происходит только для прямого создания экземпляров функциональных объектов, и не поднимается для нормальной компиляции.
- типы.GeneratorType
Тип объектов-генераторов-итераторов, созданных функции генератора.
- типы. CoroutineType
Тип объектов сопрограмм, созданных
асинхронных функций def
.Новое в версии 3.5.
- типы.AsyncGeneratorType
Тип объектов асинхронного генератора-итератора, созданных функции асинхронного генератора.
Новое в версии 3.6.
- класс типов.CodeType( **kwargs )
Тип для объектов кода, таких как возвращаемые
compile()
.Вызывает событие аудита
code.__new__
с аргументамиcode
,filename
,name
,argcount
,posonlyargcount
,kwonlyargcount
,nlocals
,размер стека
,флаги
.Обратите внимание, что проверенные аргументы могут не совпадать с именами или позициями требуется инициализатором. Событие аудита происходит только для прямого создание экземпляров объектов кода и не вызывается для обычной компиляции.
- заменить( **kwargs )
Вернуть копию объекта кода с новыми значениями для указанных полей.
Новое в версии 3.8.
- типы.CellType
Тип для объектов ячеек: такие объекты используются как контейнеры для свободные переменные функции.
Новое в версии 3.8.
- типы.MethodType
Тип методов пользовательских экземпляров класса.
- типы.BuiltinFunctionType
- типы.BuiltinMethodType
Тип встроенных функций как
len()
илиsys.exit()
и методы встроенных классов. (Здесь термин «встроенный» означает «написанный на В.)
- типы.WrapperDescriptorType
Тип методов некоторых встроенных типов данных и базовых классов, таких как
объект.__init__()
илиобъект.__lt__()
.Новое в версии 3.7.
- типы.MethodWrapperType
Тип связан с методами некоторых встроенных типов данных и базовых классов. Например, это тип
объект().__str__
.Новое в версии 3.7.
- типы .NotImplementedType
Тип
Нереализовано
.Новое в версии 3.10.
- типы.MethodDescriptorType
Тип методов некоторых встроенных типов данных, таких как
str. join()
.Новое в версии 3.7.
- типы.ClassMethodDescriptorType
Тип несвязанных методов класса некоторых встроенных типов данных, таких как
дикт.__dict__['fromkeys']
.Новое в версии 3.7.
- класс типов.ModuleType( name , doc=None )
Тип модулей. Конструктор берет имя модуль, который необходимо создать, и, возможно, его docstring.
Примечание
Используйте
importlib.util.module_from_spec()
для создания нового модуля, если вы хотите установить различные атрибуты, контролируемые импортом.- __doc__
Строка документации модуля. По умолчанию
Нет
.
- __загрузчик__
Загрузчик, загрузивший модуль. По умолчанию
Нет
.Этот атрибут должен соответствовать
importlib.machinery.ModuleSpec.loader
как хранится в объекте__spec__
.Примечание
В будущих версиях Python этот атрибут может не устанавливаться по умолчанию. Чтобы защититься от этого потенциального изменения, желательно читать из
__spec__
вместо атрибута или использоватьgetattr(module, "__loader__", None)
, если вам явно нужно использовать этот атрибут.Изменено в версии 3.4: По умолчанию
Нет
. Ранее этот атрибут был необязательным.
- __имя__
Название модуля. Ожидается совпадение
importlib.machinery.ModuleSpec.name
.
- __пакет__
К какому пакету принадлежит модуль. Если модуль верхнего уровня (т.е. не является частью какого-либо конкретного пакета), то атрибут должен быть установлен до
''
, иначе следует установить имя пакета (которое может быть__name__
, если модуль сам является пакетом). По умолчаниюНет
.Этот атрибут должен соответствовать
importlib. machinery.ModuleSpec.parent
как хранится в объекте__spec__
.Примечание
В будущих версиях Python этот атрибут может не устанавливаться по умолчанию. Чтобы защититься от этого потенциального изменения, желательно читать из
__spec__
вместо атрибута или используйтеgetattr(module, "__package__", None)
, если вам явно нужно использовать этот атрибут.Изменено в версии 3.4: По умолчанию
Нет
. Ранее этот атрибут был необязательным.
- __spec__
Запись состояния модуля, связанного с системой импорта. Ожидается, что экземпляр
importlib.machinery.ModuleSpec
.Новое в версии 3.4.
- типы.EllipsisType
Тип
Многоточие
.Новое в версии 3.10.
- класс типов.GenericAlias ( t_origin , t_args )
Тип параметризованных дженериков, таких как
список[целое число]
.t_origin
должен быть непараметризованным универсальным классом, напримерlist
,кортеж
илиdict
.t_args
должен быть кортежемt_origin
:>>> из импорта типов GenericAlias >>> list[int] == GenericAlias(list, (int,)) Истинный >>> dict[str, int] == GenericAlias(dict, (str, int)) Истинный
Новое в версии 3.9.
Изменено в версии 3.9.2: Теперь этот тип может быть подклассом.
- Типы класса . UnionType
Тип выражений типа объединения.
Новое в версии 3.10.
- класс типов.TracebackType( tb_next , tb_frame , tb_lasti , tb_lineno )
Тип объектов трассировки, например найденный в
sys.exception().__traceback__
.См. справочник по языку для получения подробной информации о доступные атрибуты и операции, а также руководство по созданию трассировок динамически.
- типы.FrameType
Тип объектов фрейма, например, найденный в
tb.tb_frame
, еслиtb
является объект трассировки.См. справочник по языку для получения подробной информации о доступные атрибуты и операции.
- типы.GetSetDescriptorType
Тип объектов, определенных в модулях расширения с помощью
PyGetSetDef
, например какFrameType.f_locals
илиarray.array.typecode
. Этот тип используется как дескриптор атрибутов объекта; имеет ту же цель, что итип свойства
, но для классов, определенных в модулях расширения.
- типы.MemberDescriptorType
Тип объектов, определенных в модулях расширения с
PyMemberDef
, например какdatetime.timedelta.days
. Этот тип используется в качестве дескриптора для простого C элементы данных, использующие стандартные функции преобразования; у него та же цель как свойствотипа
, но для классов, определенных в модулях расширения.Сведения о реализации CPython: В других реализациях Python этот тип может быть идентичен
GetSetDescriptorType
.
- класс типов. MappingProxyType ( сопоставление )
Прокси сопоставления только для чтения. Он обеспечивает динамическое представление карт записей, что означает, что при изменении отображения представление отражает эти изменения.
Новое в версии 3.3.
Изменено в версии 3.9: Обновлено для поддержки нового союза (
|
) оператор из PEP 584 , который просто делегирует базовому отображению.- ключ в прокси
Возврат
Истина
, если базовое сопоставление имеет ключ ключ , иначеЛожь
.
- прокси [ключ]
Вернуть элемент базового сопоставления с ключом ключ . Поднимает
KeyError
, если ключ не находится в базовом отображении.
- итер (прокси)
Возвращает итератор по ключам базового сопоставления. Это ярлык для
iter(proxy.keys())
.
- лен (прокси)
Возвращает количество элементов в базовом отображении.
- копировать()
Вернуть неглубокую копию базового сопоставления.
- получить ( ключ [ по умолчанию ])
Возвращает значение для ключа , если ключ находится в базовом сопоставлении, иначе по умолчанию . Если default не задано, по умолчанию используется
None
, так что этот метод никогда не вызываетKeyError
.
- элементы ()
Вернуть новое представление элементов базового сопоставления (
(ключ, значение)
пар).
- ключи()
Вернуть новое представление ключей базового сопоставления.
- значения()
Вернуть новое представление значений базового сопоставления.
- обратный (прокси)
Возвращает обратный итератор по ключам базового сопоставления.
Новое в версии 3.9.
Дополнительные классы полезности и функции
- класс типов.SimpleNamespace
Простой подкласс
объекта
, предоставляющий доступ к атрибутам пространство имен, а также осмысленное представление.В отличие от объекта
SimpleNamespace
можно добавлять и удалять атрибуты. Если объектSimpleNamespace
инициализируется ключевым словом аргументы, они добавляются непосредственно в базовое пространство имен.Тип примерно эквивалентен следующему коду:
класс SimpleNamespace: def __init__(я, /, **kwargs): self.__dict__.update(kwargs) защита __repr__(сам): items = (f"{k}={v!r}" для k, v в self. __dict__.items()) return "{}({})".format(type(self).__name__, ", ".join(items)) def __eq__(я, другой): если isinstance(self, SimpleNamespace) и isinstance(other, SimpleNamespace): вернуть self.__dict__ == другое.__dict__ вернуть нереализованный
SimpleNamespace
может быть полезен в качестве замены классаNS: pass
. Однако для структурированного типа записи используйтеnamedtuple()
вместо.Новое в версии 3.3.
Изменено в версии 3.9: Порядок атрибутов в представлении изменен с алфавитного на вставку (например,
дикт
).
- types.DynamicClassAttribute( fget=Нет , fset=Нет , fdel=Нет , doc=Нет )
Направить доступ к атрибуту класса в __getattr__.
Это дескриптор, используемый для определения атрибутов, которые действуют по-разному, когда доступ через экземпляр и через класс. Доступ к экземпляру остается нормальный, но доступ к атрибуту через класс будет перенаправлен на метод класса __getattr__; это делается путем поднятия AttributeError.