У вас есть несколько возможностей, поэтому вам придется выбирать в зависимости от конкретной ситуации, которая кажется наиболее вероятной.
Отдельно : Как и в ответе Марка Гравелла, вы можете отделить свою модельполностью от производителя и использовать внешний анализатор, который обрабатывает желаемые транзакции, выполняя определенные вызовы.Я бы использовал этот подход, только если вы не можете представить себе слой абстракции для работы поверх оригинальных библиотек DLL.
Decorator : поскольку вы хотите добавить поведение в данную библиотеку (проверьте соединение), первое, что приходит на ум, - это использование шаблона декоратора .Это в основном сводится к тому, что вы намекали в первую очередь;оборачивая всю DLL и реализуя дополнительную промежуточную логику, где это необходимо.Поскольку вы пишете декоратор вручную, существует множество изменений API, которые вы можете сделать, чтобы удовлетворить его вашим потребностям.
Proxy : в зависимости от того, насколько разнообразна эта промежуточная логика, которую вы хотите реализоватьможно использовать шаблон прокси .Например, когда все, что вы хотите сделать, это раскрыть исходные свойства и добавить одинаковое дополнительное поведение для каждого свойства.Когда классы Instrument
производителя реализуют интерфейсы, вы можете сгенерировать класс, который реализует этот интерфейс во время выполнения и перенаправляет вызовы фактической DLL производителя.Это не легко, но есть несколько библиотек, которые могут помочь вам сделать это. Castle DynamicProxy или более низкого уровня RunSharp .Подумайте только о том, чтобы идти по этому пути, когда сможете воспользоваться его преимуществами.Например, когда вы должны обернуть большую библиотеку или библиотеку, которая часто меняется со временем.
Когда все, что вам нужно сделать, это обернуть 20 свойств, я предлагаю вам использовать подход декоратора.Если у вас есть свободное время, может быть интересно поиграть с генерацией кода во время выполнения и попыткой сгенерировать прокси.
Я могу привести пример сгенерированного времени выполненияproxy , созданный с помощью RunSharp, просто чтобы дать вам представление о том, что вы хотели бы попробовать.Функция CreateGenericInterfaceWrapper<T>()
оборачивает любой интерфейс «менее универсальным» интерфейсом , генерируя при необходимости приведения.