4

我正在开发一个组件,该组件执行使用 ioc 注册的任何接口的临时方法,并且执行时刻取决于不同的触发器。它必须能够将要执行的操作保存到数据库,所以我将方法名称、类型和参数列表(序列化为 BLOB)保存到数据库中,直到需要。

当触发发生时,我需要对类型的实例执行方法。当我使用依赖注入时,我将接口名称保存到数据库中(格式"Namespace.IInterface, AssemblyName"

要在 ioc 容器上运行Resolve<IInterface>()方法,我需要它的实例Type

Assembly assembly = System.Reflection.Assembly.Load(assemblyName);
Type service = assembly.GetType(typeName);
object instance = IOCContainer.Resolve(service);

我的问题是:

  • 如果我确定包含程序集已加载到应用程序域中,是否有更好的方法从其名称中获取类型的实例?(我尝试过简单Type.Load(typeName)但为空)
  • 如果相关程序集已加载,CLR 是否会优化该过程(使用已加载),还是我需要手动缓存程序集列表以防止反复加载相同程序集对性能的影响?
4

4 回答 4

5
  • 如果typeName您使用包含程序集名称(类似MyNamespace.MyType, MyAssembly version=1.0.0.0,publicKeyToken=12345etc),那么Type.Load(typeName)将获得您的类型但不为空;
  • CLR 只负责加载程序集一次(每个上下文一次,详细信息在这里,在您的情况下,上下文保持不变,所以答案是您应该放松并将缓存留给 CLR :))。
于 2012-09-04T10:31:40.193 回答
3

如果我确定包含程序集已加载到应用程序域中,是否有更好的方法从其名称中获取类型的实例?(我尝试了简单的 Type.Load(typeName) 但得到了空值)

不。

如果相关程序集已加载,CLR 是否会优化该过程(使用已加载)

是的。

每个程序集仅加载一次。

于 2012-09-04T10:32:15.580 回答
2

如果相关程序集已加载,CLR 是否会优化该过程(使用已加载)

这个问题的答案在MSDN 文章How the Runtime Locates Assemblies 的第2 步

如果在以前的调用中也请求了所请求的程序集,则公共语言运行库将使用已加载的程序集。在命名构成应用程序的程序集时,这可能会产生影响。有关命名程序集的详细信息,请参阅程序集名称


与问题没有直接关系,但也很有用:

如果对程序集的先前请求失败,则对程序集的后续请求将立即失败,而不会尝试加载程序集。从 .NET Framework 2.0 版开始,程序集绑定失败被缓存,缓存的信息用于确定是否尝试加载程序集。

于 2012-09-04T13:34:39.750 回答
1

为了验证性能影响,我尝试加载相同的程序集 n 次。并发现总分配的内存随着每次调用而增长。

要尝试执行以下操作:

while (true)
{
    Assembly assembly = Assembly.LoadFrom("abc.dll");
    //monitor: AppDomain.CurrentDomain.MonitoringTotalAllocatedMemorySize
    //memory growing with each call
}

==============

然后我这样做是为了确保我只加载一次程序集。

var typeName = "Namespace.ClassName, Namespace";

while (true)
{
   var typeFound = Type.GetType(typeName);
   if (typeName == null)
   {
       Assembly assembly = Assembly.LoadFrom("abc.dll");
   }
   //monitor: AppDomain.CurrentDomain.MonitoringTotalAllocatedMemorySize
   //memory will not grow after first call
}
于 2017-01-10T06:40:52.580 回答