Инжекция на основе отражений и динамический прокси: практические соображения? - PullRequest
2 голосов
/ 05 мая 2011

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

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

public interface IConfiguration
{
    dynamic Get(string key);
    void Set(string key, dynamic value);
}

Что я планирую сделать, так это реализовать некоторый синтаксис беглого отображения или просто украсить классы компонентов такими атрибутами, как:

public class MyComponent : IActivity
{
    [Configuration("Threshold")]
    public virtual int Threshold { get; set; }

    [Configuration("SomeKey", Persistence = ConfigPersistence.Save)]
    public virtual string SomeSetting { get; set; }
}

Вы получите картину ... надеюсь. Важно отметить, что некоторые свойства действительно должны быть сохранены обратно в хранилище , поэтому обычные библиотеки DI здесь не работают; и даже если они это сделали, это тупые инструменты, не предназначенные для раскрутки сотен тысяч компонентов и загрузки / сохранения миллионов атрибутов. Другими словами, Я не думаю, что заново изобретаю колесо , но если кто-то хочет убедить меня в обратном, не стесняйтесь.

В любом случае, я рассматриваю два возможных варианта обработки «внедрения» данных конфигурации в эти экземпляры компонентов:

  1. Простое ванильное отражение - отсканируйте тип для атрибутов конфигурации и сохраните информацию об участнике (вместе с ключом конфигурации) в статическом словаре. Затем используйте методы отражения, такие как PropertyInfo.SetValue и PropertyInfo.GetValue для впрыска и извлечения (из-за отсутствия лучшего термина). Это похоже на подход, используемый большинством библиотек DI.

  2. Используйте динамический прокси, такой как Castle, и подключите перехватчик к оформленным свойствам, так что вместо ссылки на частные / автоматически сгенерированные поля они ссылаются на экземпляр IConfiguration (то есть вызовы метода get IConfiguration.Get и set вызывает метод IConfiguration.Set). Это похоже на подход, используемый NHibernate и другими ORM.

Полная реализация может оказаться довольно трудоемкой, так что я не хочу идти слишком далеко по неверному пути, прежде чем понять, что я что-то пропустил.

Итак, мой вопрос: Каковы плюсы / минусы любого из подходов и каких подводных камней мне следует избегать? Я думаю в общих чертах о производительности, ремонтопригодности, защите от идиотов, и т.д.

Или, альтернативно, есть другие, более быстрые пути к этой цели, предпочтительно, которые не имеют крутых кривых обучения?

1 Ответ

0 голосов
/ 21 января 2012

Динамический прокси гораздо лучше подходит. Определите перехватчик «конфигурации», который вводит значение из конфигурации в ваш компонент (желательно лениво). Используя динамический прокси-сервер, я бы также реализовал универсальный интерфейс IDisposable для вашего прокси-компонента, чтобы при удалении или удалении объекта GC он сохранял значения конфигурации на основе установленного в вашем атрибуте флага постоянства.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...