Как использовать атрибуты C# и рефлексию для внедрения / форсирования поздних привязок на отмеченных объектах?

Я люблю шаблоны проектирования, проблема в том, что некоторые из них могут быть очень утомительными для реализации. Например, украшение объекта, имеющего более 20 членов, просто раздражает.

Итак, я хотел создать хорошую библиотеку шаблонов проектирования, которые будут применяться к классам (как базовые классы или атрибуты), чтобы сделать реализацию этих шаблонов намного быстрее и проще.

Проблема в том... Я не совсем уверен, с чего начать - потому что я в основном не знаком с атрибутами и рефлексией.


Я хотел бы использовать атрибуты для пометки Singletons (аналогично тегу Export), Multitons и Decorators... если это вообще возможно. Но я даже не знаю, с чего начать, чтобы создать одноэлементный атрибут, который изменяет функциональность его экземпляров.

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

Фреймворк, который я обнаружил и назвал Ninject 1.0, создал атрибут Singleton, но библиотека настолько обширна и не имеет документов, что в настоящее время я не могу следовать ее логике.


Я чувствую, что библиотека с такой функциональностью будет большим вкладом для многих разработчиков. Таким образом, было бы очень полезно, если бы кто-то мог предоставить некоторый пример кода, который указал бы мне в правильном направлении, чтобы создать один из этих шаблонов в качестве атрибута - чей код не слишком задействован. Или, если кто-то захочет провести меня через реализацию одноэлементного атрибута Ninject, чтобы я мог поработать над этим...

Спасибо за ваше время и внимание.

1 ответ

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

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

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

Теперь, после всего этого, действительно можно увидеть, что то, что вы планируете делать, не является правильным способом реализации шаблонов. Вы не помечаете код атрибутами и т. Д., А затем называете их шаблонами. Шаблон - это ваш код. Ваш код является шаблоном. Например, вы не помечаете шаблон издателя / подписчика в классе, если он действительно не реализует функции публикации / подписки. Например, вы не помечаете класс "Singleton", и тогда он становится одноэлементным шаблоном; использование шаблона Singleton требует, чтобы вы кодировали свою программу (и ваши классы) вокруг этого проекта.

Однако вы можете пометить код или классы определенными атрибутами, которые могут помочь в проверке соответствия кода / классов определенному шаблону.

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

Но атрибуты и отражение обычно не являются инструментами для реализации шаблона.

В C#, где нет множественного наследования, способ реализации шаблонов иногда только через базовый класс. Например, вы можете реализовать шаблон "singleton", объявив базовый класс "SingletonObject", который ограничивается только одним экземпляром. Затем вы выводите из этого базового класса любой класс, которым хотите быть в одиночку. Например, вы можете реализовать шаблон "публикация / подписка", объявив интерфейсы IPublisher и ISubscriber.

Теперь, если вы действительно хотите просто использовать шаблон Decorator на классах C# (в соответствии с заголовком вашего вопроса), то вам нужен автоматический генератор объектов-оболочек. Вы можете основывать свою оболочку на ExpandoObject, проходить через свойства базового объекта и добавлять свойства к ExpandoObject, который просто делегирует обратно базовому объекту. Затем добавьте новые свойства в ExpandoObject поверх вашего базового объекта. Вуаля! Вы получаете генератор классов-обёрток auto-Decorator-Pattern.

Другие вопросы по тегам