为什么我不能从其他程序集加载类
本文关键字:程序集 加载 其他 不能 为什么 | 更新日期: 2023-09-27 18:37:24
在我的MVC项目的web.config
中,我有这个:
<appSettings>
<add key="MembershipRepository" value="Repo.MembershipRepository"/>
</appSettings>
我有这样的代码:
var appSettings = ConfigurationManager.AppSettings;
string membershipRepositoryClassName = appSettings["MembershipRepository"];
Type membershipRepositoryType = Type.GetType(membershipRepositoryClassName);
IMembershipRepository repository = (IMembershipRepository)Activator.CreateInstance(membershipRepositoryType);
假设包含 web.config
的 Web 应用程序位于程序集Web
中。我给出的代码段在汇编Lib
中。类MembershipRepository
位于汇编Repo
中。 Web
提到了Lib
和Repo
。 Lib
没有对任何其他程序集的引用(它被引用为 dll)。 Repo
可能引用也可能没有引用Lib
。
我得到membershipRepositoryType
是null
.我知道也许我需要指定MembershipRepository
所在的程序集。一种方法是在配置中指定程序集名称(如下所示)。但我认为应该有一些其他方法。否则如何加载其他类仅从配置文件中获取类名?例如,MembershipProvider
类可以从其他程序集很好地加载。
我怎么能做同样的事情。或者如果我不能,为什么我不能?
来自 MSDN 库文档的Type.GetType(String)
:
类型名称:要获取的类型的程序集限定名称。请参阅程序集限定名称。如果类型位于当前正在执行的程序集或 Mscorlib.dll 中,则提供由其命名空间限定的类型名称就足够了。
最后一句话解释了为什么当你只指定类名时它有时有效:如果执行代码在 Repo
中,那么你可以只指定MembershipProvider
。但是,为了清楚起见(以及性能),我建议避免此行为并始终指定程序集名称。或者,如果已经具有对包含您的类型的Assembly
的引用,则可以改为调用Assembly.GetType
。
不过,如果您确实遇到不知道哪个程序集包含您的类型的情况,则可以搜索当前 AppDomain 中的所有已加载程序集,并尝试对每个程序集调用 Assembly.GetType
:
Type type = AppDomain.CurrentDomain.GetAssemblies()
.Select(assembly => assembly.GetType(typeName))
.First(t => t != null);
你要找的是这样的:
var types = AppDomain.CurrentDomain.GetAssemblies().ToList()
.SelectMany( s => s.GetTypes() )
.Where( p => p.Name == membershipRepositoryClassName );
这实际上将返回一个列表,因为具有相同名称的类型可以在多个程序集中声明。如果您确定只有一种类型,则可以将.FirstOrDefault()
或.Single()
添加到链的末尾。如果不确定类型是否存在,请使用 .FirstOrDefault()
,如果不存在,则希望它返回 null。如果您确定类型应该存在,并且希望它在找不到类型时引发异常,请使用 .Single()
。