我有一个 bootstrap 程序,可以查看ASP中的所有程序集.NET MVC应用程序来查找实现IBootstrapperTask
接口的类型,然后将它们注册到IOC Contrainer.这个 idea 是,你可以把你的iBootTrapper任务放在任何地方,并随心所欲地组织你的项目.
bootstrap 程序代码:
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 one的程序集,但这并不影响我).
但是,如果AppDomain重新启动,或者我"跳转"了Web.配置文件(添加一个空格并保存),静态构造函数会再次运行,但当调用AppDomain.CurrentDomain.GetAssemblies()
时,会运行most of the Assemblies are missing,包括包含我的ibootstrapper任务类型的构造函数.
我怎么才能绕过这个问题呢?我想我可以对/bin目录执行System.IO操作,然后手动加载其中的所有DLL,但如果可能的话,我宁愿避免这样做,或者这是唯一的方法吗?我对这件事采取的总体方法是正确的吗?
这是一个运行在.NET4.0上的ASP.NETMVC2.0应用程序,我在内置的Visual Studio2010Cassini Web服务器和Windows Server2008的集成管道模式下的IIS7.0中遇到了这个问题.
Edit:我刚刚遇到过这样的帖子Difference between AppDomain.GetAssemblies and BuildManager.GetReferencedAssemblies,它说AppDomain只在需要时加载程序集(例如,当第一次调用该程序集中的方法/类时).我想这可以解释为什么AppDomain.CurrentDomain.GetAssemblies()
上没有程序集,因为 bootstrap 程序很早就运行了.
我注意到,如果我在 bootstrap 程序之前从丢失的程序集中调用"某物",例如:
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
MyApp.MissingAssembly.SomeClass someClass =
new MyApp.MissingAssembly.SomeClass();
Bootstrapper.Run();
}
}
...它似乎解决了问题,但有点像黑客.