我有一个 Bootstrapper,它可以查看 ASP.NET MVC 应用程序中的所有程序集,以查找实现IBootstrapperTask
接口,然后将它们注册到 IOC 容器。这个想法是,您实际上可以将 IBootstrapperTasks 放置在任何地方,并按照您喜欢的方式组织您的项目。
引导程序代码:
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,但如果可能的话宁愿避免这种情况,或者这是唯一的方法吗?我是否采取了正确的一般方法来解决这个问题?
这是在 .NET 4.0 上运行的 ASP.NET MVC 2.0 应用程序,我在使用内置 Visual Studio 2010 Cassini Web 服务器以及 Windows Server 2008 上集成管道模式下的 IIS7.0 时遇到此问题。
Edit:我刚刚看到这个帖子AppDomain.GetAssemblies 和 BuildManager.GetReferencedAssemblies 之间的区别 https://stackoverflow.com/questions/2477787/difference-between-appdomain-getassemblies-and-buildmanager-getreferencedassembli这表示 AppDomain 仅在需要时加载程序集(例如,当首次调用该程序集中的方法/类时)。我想这可以解释为什么大会失踪了AppDomain.CurrentDomain.GetAssemblies()
因为 Bootstrapper 很早就运行了。
我注意到如果我在引导程序之前从丢失的程序集中调用“某些东西”,例如:
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
MyApp.MissingAssembly.SomeClass someClass =
new MyApp.MissingAssembly.SomeClass();
Bootstrapper.Run();
}
}
...这似乎解决了问题,但它有点像黑客。