- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我有一个 Bootstrapper,它查看 ASP.NET MVC 应用程序中的所有程序集以查找实现 IBootstrapperTask
接口(interface)的类型,然后将它们注册到 IOC Contrainer。这个想法是您可以直接将 IBootstrapperTasks 放在任何地方,并按照您喜欢的方式组织您的项目。
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 程序集,但这并不影响我)。
但是,如果 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 时遇到了这个问题。
编辑: 我刚刚看到这篇 SO 帖子 Difference between AppDomain.GetAssemblies and 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();
}
}
...它似乎解决了问题,但它有点乱。
最佳答案
我查看了 ASP.NET MVC 2.0 源代码并查找了 AreaRegistration.RegisterAllAreas();
是如何实现的。此行通常放入 Global.asax Application_Start() 方法,并在内部扫描所有程序集以查找实现 AreaRegistration 抽象类型的类型。这有点像我所追求的行为。
RegisterAllAreas() 似乎调用了 BuildManager.GetReferencedAssemblies()
,如果它对 MVC 足够好,那么对我来说也足够好:-)
我已经做了一些实验,BuildManager.GetReferencedAssemblies() 甚至会选择临时的随机 DLL 放入/bin 文件夹,即使没有引用 Visual Studio 解决方案中的任何项目。所以它看起来比 AppDomain.Current.GetAssemblies()
可靠得多。
我已将我的程序集定位器代码重写为以下内容:
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.Compilation;
public static class AssemblyLocator
{
private static readonly ReadOnlyCollection<Assembly> AllAssemblies;
private static readonly ReadOnlyCollection<Assembly> BinAssemblies;
static AssemblyLocator()
{
AllAssemblies = new ReadOnlyCollection<Assembly>(
BuildManager.GetReferencedAssemblies().Cast<Assembly>().ToList());
IList<Assembly> binAssemblies = new List<Assembly>();
string binFolder = HttpRuntime.AppDomainAppPath + "bin\\";
IList<string> dllFiles = Directory.GetFiles(binFolder, "*.dll",
SearchOption.TopDirectoryOnly).ToList();
foreach (string dllFile in dllFiles)
{
AssemblyName assemblyName = AssemblyName.GetAssemblyName(dllFile);
Assembly locatedAssembly = AllAssemblies.FirstOrDefault(a =>
AssemblyName.ReferenceMatchesDefinition(
a.GetName(), assemblyName));
if (locatedAssembly != null)
{
binAssemblies.Add(locatedAssembly);
}
}
BinAssemblies = new ReadOnlyCollection<Assembly>(binAssemblies);
}
public static ReadOnlyCollection<Assembly> GetAssemblies()
{
return AllAssemblies;
}
public static ReadOnlyCollection<Assembly> GetBinFolderAssemblies()
{
return BinAssemblies;
}
}
关于c# - ASP.NET - AppDomain.CurrentDomain.GetAssemblies() - AppDomain 重启后程序集丢失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3552223/
所以我的问题围绕着节省内存。 本质上,我需要将程序集加载到主域/当前域以外的单独应用程序域中,检查该程序集中的类型,然后在完成后卸载新域。 目前我的解决方案如下: AppDomain NewDomai
我想枚举 Asp.NET 应用程序中所有加载的程序集,使用 AppDomain.CurrentDomain.GetAssemblies() .但是,在检查 AppDomain 的文档时,我发现以下语句
当我需要在关闭应用程序之前使用 Stop() 函数停止后台线程时,我有一个简单的应用程序。问题是我的 Main() 函数有几个退出点(返回语句) static void Main(string[] a
我有一个带有绑定(bind)到 Application.CurrentDomain.UnhandledException 的事件处理程序的 .NET 程序。 运行带有调试的程序时,当抛出未处理的异常时
我有一个全局异常处理程序,可以在Main.cs中很好地工作,但是在捕获到错误后,我的应用程序不存在了,而只是挂起了。我尝试了Environment.Exit,退出选择器,返回,重新抛出异常-所有这些仍
我目前正在使用以下代码: AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => { var name = args.Name
我想在发生未处理的异常时在问题跟踪器系统中创建错误报告。由于这是通过一系列异步http请求完成的,所以对应的方法是async return a task: AppDomain.CurrentDomai
我在单独的类库项目中有电子邮件模板(和电子邮件发送器)。我正在获取 View 路径(复制到输出目录 = true),如下所示: var basePath = AppDomain.CurrentDoma
在 VS2012 中,我有一堆 (MS) 单元测试,它们使用我存储在与测试文件类相同的文件夹中的不同 xml/文本文件。 我使用 File.OpenRead(AppDomain.CurrentDoma
我有一个程序集,当访问它时,它会启动一个线程来处理放置在队列中的项目。在该程序集中,我将一个处理程序附加到 DomainUnload 事件: AppDomain.CurrentDomain.Domai
我想遍历我在项目中添加的所有类 Assembly[] foo = AppDomain.CurrentDomain.GetAssemblies(); foreach(Assembly a in foo)
我有一个 WCF 服务,在 Global.asax 中有以下代码: protected void Application_Start(object sender, EventArgs e) {
我正在尝试使用 CurrentDomain.AssemblyResolve 事件来加载标记为嵌入式资源的 DLL。具体来说,我的问题来自于我试图将程序集用作子类的事实,如下所示: #define BR
我试图根据答案实现解决方案 How to handle exceptions raised in other threads when unit testing? ,但我仍然不明白在处理程序中做什么。
我已经设置了 UnhandledException 以在我的服务崩溃之前记录任何异常。 AppDomain.CurrentDomain.UnhandledException += new Unhand
在找到关于程序集解析 (AppDomain.CurrentDomain.AssemblyResolve asking for a .resources assembly?) 的最后一个问题的答案后,我
如何将 AppDomain.CurrentDomain.BaseDirectory 的相对路径获取到 Uri 中。 我需要从 AppDomain.CurrentDomain.BaseDirectory
总的来说,我试图从主域中的 dll 执行方法,但之后,卸载该 dll。到目前为止,我已经创建了新的 AppDomain 并在那里加载了 Assembly\dll,使用 MarshalByRefObje
我遇到了一个问题,我的单元测试没有在我的 TFS 构建机器上运行,尽管它们正在我的开发人员机器上运行。 我在以下行中遇到异常,试图为特定接口(interface)加载所有加载的程序集: var
我在使用 ReSharper (8.2.2) 和 VS 2013 运行我的测试用例时遇到了一个奇怪的错误。 演示该问题的简化测试用例仅包含两行代码: CallContext.LogicalSetDat
我是一名优秀的程序员,十分优秀!