- 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/
我使用加密狗来保护我的可执行文件。加密狗以两种方式保护软件: 在代码中调用读/写加密狗内存(例如存储功能数据),使用加密狗中的算法加密/解密数据。加密 key 是只可写的。 加密 EXE 文件并使用加
我正在寻找一种将当前应用程序的程序集放入可移植库项目中的方法。 在经典库项目中,下面的代码行完成了这项工作: var assemblies = System.AppDomain.CurrentDoma
我想知道调用这些方法中的任何一个有什么好处(如果有的话),为什么? 它们在功能上是否相同,还是我应该始终选择一个而不是另一个? 最佳答案 据我所知,它们在功能上是等效的,但是 Assembly.Get
我快要疯了! 我接近 this post 中的答案,但该包中没有 DependencyContext.Default。 最佳答案 没有等效项 - UWP/PCL 不支持。 在 PCL 中不受支持,因为
只是想知道在完全信任的 asp.net mvc 2 应用程序的上下文中两者之间是否有任何区别。 最佳答案 .NET Framework 推迟将程序集加载到当前 AppDomain 中,直到需要它们为止
在 MSDN 中,据说 AppDomain.GetAssemblies() is supported in Silverlight 4 . 在我的项目中,当我以 Silverlight 版本 4 为目
请建议哪个最适合获取执行程序集位置。 Assembly.GetAssembly(typeof(NUnitTestProject.RGUnitTests)).Location 或 Assembly.Ge
在单元测试期间,我遇到了以下代码的问题,该代码要求所有已加载的程序集: var res = AppDomain.CurrentDomain.GetAssemblies() .SelectMany(x
我有一些代码循环遍历当前加载到在 ASP.NET 应用程序中运行的 AppDomain 中的类型。以下是我获取程序集的方式: var assemblies = AppDomain.CurrentDom
我有一个 Bootstrapper,它查看 ASP.NET MVC 应用程序中的所有程序集以查找实现 IBootstrapperTask 接口(interface)的类型,然后将它们注册到 IOC C
编辑:这之前的标题是“IIS 重启和应用程序初始化之间的应用程序初始化行为不同”。我更改了标题以从 IIS/Application Initialisation 扩展问题,因为观察到的行为与 AppD
我想我使用了一个很常见的模式: var result = from a in AppDomain.CurrentDomain.GetAssemblies()
我想我使用了一个很常见的模式: var result = from a in AppDomain.CurrentDomain.GetAssemblies()
收到此警告(即使 variant.getAssemble() 未在任何地方使用): API 'variant.getAssemble()' is obsolete and has been repla
收到此警告(即使 variant.getAssemble() 未在任何地方使用): API 'variant.getAssemble()' is obsolete and has been repla
我是一名优秀的程序员,十分优秀!