通过反射加载的 DLL 是否被缓存?
Are DLLs loaded by reflection being cached?
我有一个根据需要通过反射加载类型的应用程序,因为实现可能会因配置而改变。
这是一个示例代码:
var myObject = Activator.CreateInstance(Type.GetType("MyAssembly.MyClass, MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1r46a5dfa04dase2"))as IMyClass
我的问题是,这个类型是默认缓存还是每次都会重新加载,如果没有,我如何缓存它以提高性能?
与实例不同,单一类型及其包含的程序集一旦使用,就不会卸载(假设只有一个 AppDomain),所以基本上答案是肯定的,有一个缓存。
也可以看看这里:
Can you remove an Add-ed Type in PowerShell again?
程序集一旦加载就无法卸载(除非您卸载加载它的完整 AppDomain)(参见示例 How to unload an assembly from the primary AppDomain?)。所以你的问题正好相反:-)
现在...您肯定可以加快一切速度:
Type myType = Type.GetType("MyAssembly.MyClass, MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1r46a5dfa04dase2");
这个调用每次都需要执行。虽然不会加载程序集,但会在程序集中进行搜索。您可以缓存 myType
.
var myObject = Activator.CreateInstance(myType) as IMyClass;
这将每次为 myType
搜索无参数构造函数。您可以通过缓存所需的构造函数 (myConstructor
) 来加快速度:
ConstructorInfo myConstructor = myType.GetConstructor(Type.EmptyTypes);
var myObject = myConstructor.Invoke(null) as IMyClass;
现在...即使使用反射也很慢...您可以创建一个动态方法来调用构造函数并将其缓存:
Func<IMyClass> myCreate = Expression.Lambda<Func<IMyClass>>(Expression.New(myConstructor)).Compile();
var myObject = myCreate();
所以最后你只能缓存 myCreate
:-)
我有一个根据需要通过反射加载类型的应用程序,因为实现可能会因配置而改变。 这是一个示例代码:
var myObject = Activator.CreateInstance(Type.GetType("MyAssembly.MyClass, MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1r46a5dfa04dase2"))as IMyClass
我的问题是,这个类型是默认缓存还是每次都会重新加载,如果没有,我如何缓存它以提高性能?
与实例不同,单一类型及其包含的程序集一旦使用,就不会卸载(假设只有一个 AppDomain),所以基本上答案是肯定的,有一个缓存。
也可以看看这里: Can you remove an Add-ed Type in PowerShell again?
程序集一旦加载就无法卸载(除非您卸载加载它的完整 AppDomain)(参见示例 How to unload an assembly from the primary AppDomain?)。所以你的问题正好相反:-)
现在...您肯定可以加快一切速度:
Type myType = Type.GetType("MyAssembly.MyClass, MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1r46a5dfa04dase2");
这个调用每次都需要执行。虽然不会加载程序集,但会在程序集中进行搜索。您可以缓存 myType
.
var myObject = Activator.CreateInstance(myType) as IMyClass;
这将每次为 myType
搜索无参数构造函数。您可以通过缓存所需的构造函数 (myConstructor
) 来加快速度:
ConstructorInfo myConstructor = myType.GetConstructor(Type.EmptyTypes);
var myObject = myConstructor.Invoke(null) as IMyClass;
现在...即使使用反射也很慢...您可以创建一个动态方法来调用构造函数并将其缓存:
Func<IMyClass> myCreate = Expression.Lambda<Func<IMyClass>>(Expression.New(myConstructor)).Compile();
var myObject = myCreate();
所以最后你只能缓存 myCreate
:-)