2013-03-05 5 views
4

Я ищу хорошую реализацию «горячей» замены в .NET. Необходимые вещи:Есть ли эталонная реализация горячей замены в .NET?

  • Возможность развернуть библиотеки DLL в определенной папке и запустить их под управлением.
  • После того, как работающая система обновит соответствующие ссылки в контейнере.

Я искал MEF и его механизм загрузки каталогов, но это кажется очень ненадежным. Может быть, у кого-то есть альтернативная реализация?

+0

Почему, на ваш взгляд, MEF ненадежен? На что еще вы посмотрели? Такой вопрос дизайна может быть лучше на [Programmers.SE], но вам нужно будет предоставить более подробную информацию и показать, что вы рассмотрели. – ChrisF

+1

Каким образом вы хотите, чтобы это было с возможностью горячей замены? Должны ли вы быть в состоянии заменить существующую сборку, пока старый используется? –

+0

Сколько вы готовы платить за эту функцию? Пересечение границы AppDomain не является дешевым (и это единственный способ в .Net изолировать DLL с одинаковым идентификатором) ... Использует ли IIS модель (сброс AppDomain на смену binaries/config)? –

ответ

6

Вы можете предоставить специальный обработчик событий для AssemblyResolve, позвонив по номеру newAppDomain(). Поставьте свой каталог таким образом AppDomain. При загрузке типа используйте функцию loadFromAppDomain(), чтобы вернуть ее. Это должно позволить вам копировать новые dll на C:\dlls во время выполнения и перезагружать оттуда. (Простите, я перевел это из своего источника VB в C# в соответствии с вашим тегом.)

String dllFolder = "C:\\dlls"; 

public void newAppDomain() 
{ 
    AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(assemblyResolve); 
} 

private static Assembly assemblyResolve(Object sender, ResolveEventArgs args){ 
    String assemblyPath = Path.Combine(dllFolder, new AssemblyName(args.Name).Name + ".dll"); 
    if(!File.Exists(assemblyPath)) 
    { 
     return null; 
    } 
    else 
    { 
     return Assembly.LoadFrom(assemblyPath); 
    } 
} 

private Type loadFromAppDomain(String className) 
{ 
    Assembly[] asses = AppDomain.CurrentDomain.GetAssemblies(); 
    List<Type> types = new List<Type>(); 
    foreach(Assembly ass in asses) 
    { 
     Type t = ass.GetType(className); 
     if(t != null) types.Add(t); 
    } 
    if(types.Count == 1) 
     return types.First(); 
    else 
     return null; 
} 
+0

+1 для тщательного ответа. Так Microsoft намерена для вас «горячей» замены. – evanmcdonnal

+4

+ 1. Этот подход, очевидно, работает только для строго типизированных, правильно версированных сборок. @evanmcdonnal, боковое примечание - пожалуйста, никогда не сокращайте сборку до 3 букв ... выглядит забавно, пока вам не нужно попросить кого-нибудь прочитать ваш код, особенно тот, у кого не слишком развитое чувство юмора. –

+1

@Alexei Надеюсь, у всех нас есть хорошие чувства юмора. Я согласен с строго типизированными сборками версий. OP не вдавался в эту деталь, но подход хорошо работает в моей среде. – djv

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