У меня есть Bootstrapper, который просматривает все сборки в приложении ASP.NET MVC, чтобы найти типы, которые реализуют интерфейс IBootstrapperTask
, а затем регистрирует их с помощью IOC Contrainer.Идея состоит в том, что вы можете буквально размещать свои задания IBootstrapper в любом месте и организовывать свои проекты так, как вам удобно.
Код для Bootstrapper:
public class Bootstrapper
{
static Bootstrapper()
{
Type bootStrapperType = typeof(IBootstrapperTask);
IList<Assembly> assemblies = AppDomain.CurrentDomain.GetAssemblies();
List<Type> tasks = new List<Type>();
foreach (Assembly assembly in assemblies)
{
var types = from t in assembly.GetTypes()
where bootStrapperType.IsAssignableFrom(t)
&& !t.IsInterface && !t.IsAbstract
select t;
tasks.AddRange(types);
}
foreach (Type task in tasks)
{
if (!IocHelper.Container().Kernel.HasComponent(task.FullName))
{
IocHelper.Container().AddComponentLifeStyle(
task.FullName, task, LifestyleType.Transient);
}
}
}
public static void Run()
{
// Get all registered IBootstrapperTasks, call Execute() method
}
}
После полной сборки AppDomain.CurrentDomain.GetAssemblies()
возвращает все сборкив моем решении (включая все GAC, но это меня не беспокоит).
Тем не менее, если перезапустить AppDomain или я отскочил от файла Web.Config (добавив пробел и сохранив),статический конструктор запускается снова, но когда вызывается AppDomain.CurrentDomain.GetAssemblies()
, большинство сборок отсутствует , включая тот, который содержит мои типы IBootstrapperTask.
Как мне обойти эту проблему?Я полагаю, я мог бы создать каталог System.IO в каталоге / bin и вручную загрузить все библиотеки DLL, но я бы предпочел избежать этого, если это возможно, или это единственный способ?Правильно ли я придерживаюсь общего подхода к этому?
Это приложение ASP.NET MVC 2.0, работающее в .NET 4.0, я получаю эту проблему со встроенным веб-сервером Visual Studio 2010 Cassini и с IIS7.0 в режиме интегрированного конвейера в Windows Server 2008.
Редактировать: Я только что натолкнулся на эту публикацию SO Разница между AppDomain.GetAssemblies и BuildManager.GetReferencedAssemblies в котором говорится, что AppDomain загружает сборки только тогда, когда они нужны (например, когда метод / класс из этой сборки вызывается впервые).Я думаю, это объяснило бы, почему сборки отсутствуют на AppDomain.CurrentDomain.GetAssemblies()
, поскольку Bootstrapper запускается очень рано.
Я заметил, что я сделал вызов чему-то из отсутствующей сборки перед Bootstrapper, например:
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
MyApp.MissingAssembly.SomeClass someClass =
new MyApp.MissingAssembly.SomeClass();
Bootstrapper.Run();
}
}
... кажется, это решает проблему, но это немного взломать.