2010-01-22 3 views
1

Я хочу выпустить DLL, которая содержит некоторые классы для использования другими разработчиками. За этими классами стоит еще одна DLL, которая связывает функциональные возможности contatain. В среде разработки я хочу, чтобы эта backend DLL имела ориентированные на развитие функции, но когда код переносится в производственную среду, я хочу, чтобы эта внутренняя библиотека была реальной. Каков наилучший способ переключить эту внутреннюю DLL?коммутатор DLL на основе среды - .net

Благодарим за помощь.

+0

Можете ли вы расширить на то, что вы имеете в виду под «развития ориентированных функций», это просто дополнительная вырубка лесов, или вы меняете поведение в какой-то существенным образом? – ScottS

+0

Это больше, чем просто регистрация. Мы занимаемся протоколированием с использованием реализаций трассировки/отладки. Я думаю, лучший ответ заключается в том, что мы существенно меняем поведение. – Sako73

ответ

0

Использование файла .config для хранения имени сборки, которую вы хотите запустить, и когда пустая/отсутствующая загружает бэкэнд-версию. [подробнее] Это проще всего сделать с другой сборкой, содержащей общие интерфейсы.

+0

Не могли бы вы указать мне пример того, как это сделать? Еще раз спасибо. – Sako73

+0

Я экспериментировал, и кажется, что до тех пор, пока я определяю одни и те же классы, а имена DLL остаются неизменными, физически изменение DLL в каталоге отлично работает. Знаете ли вы о каких-либо проблемах или падениях этого подхода? – Sako73

+0

Один из способов - использовать инструмент IOC, такой как Autofac http://code.google.com/p/autofac/. Другим является использование Assembly.Load или как описано в этой ссылке http://stackoverflow.com/questions/370286/c-interface-call-method-in-different-project-assembly – kenny

-1

Попробуйте пометить классы «Только для разработчиков» с помощью условного атрибута. Такие как:

[Conditional("DEBUG")] 
public class DeveloperClass 
{ 
    // ... 
} 

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

+0

Проблема заключается в том, что использование этого атрибута вызовет или не вызовет метод, но не изменит сам метод. Однако # if/# else/# endif работает, и будет разрешен только один набор файлов кода. – Sako73

-1

Итак, я предполагаю, что и ваши DLL разработки, и DLL 'production' имеют один и тот же интерфейс?

Если это так, у вас есть только Wrapper над dll, и Wrapper перенесет все функции в dll (интерфейс будет одинаковым для обеих версий dll).

Используйте следующий код для загрузки библиотеки,

if(PRODUCTION) { 
     target_lib = "productionlib.dll"; 
} else { 
     target_lib = "developmentlib.dll"; 
} 
lib = LoadLibrary(target_lib); 

обертка будет просто вперед функция вызовы к соответствующему загруженной библиотеке (либо производство или библиотека разработки, как описано выше)

functionptr=(LPFunctionType)GetProcAddress(lib,"TargetFunction"); 
if(functionptr) { functionptr(bs); } 
0

После этого на ваш комментарий:

Я экспериментировал, и это показывает, что пока я определяю таких же классов, а имена DLL остаются то же самое, физически меняя DLL в каталоге работает отлично. У вас есть какие-либо проблемы с или проблемы с ?

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

PROGRAM -> REFERENCED DLL -> [One of two "Backend DLL's] 

Было бы создать абстрактные классы/интерфейсы в «Реферировано DLL», которые определяют классы/методы, что и в «Backend DLL "должна быть показана, а затем ссылаться на справочную библиотеку DLL« REFERENCED DLL »и реализовывать фактические классы поверх абстрактных классов/интерфейсов.

Например, программа «Program» ожидает использования класса «Logger» в REFERENCED.DLL, который использует методы в класах под названием «BackEndLogger» в BACKEND.DLL (будь то разработка или версия для производства). Итак, в ССЫЛКАХ.DLL есть класс, такие как:

public abstract class BackEndLogger 
{ 
    public virtual void LogEvent(string eventToLog) 
} 

Затем в обеих версиях «BACKEND.DLL», есть класс, таких как:

public class Logger : BackEndLogger 
{ 
    public override void LogEvent(string eventToLog) 
    { 
    ... code for implementation goes here 
    } 
} 

REFERENCED.DLL будет иметь ссылку на DLL под названием «BACKEND.DLL», и потому, что интерфейсы классов точно такие же (в значительной степени обеспеченные, если синхронизировать их, реализуя абстрактные классы/интерфейсы в REFERENCED.DLL), не будут более мудрыми.

Надеемся, что это сделал какой-то смысл =)

Смежные вопросы