为什么我不能从其他程序集加载类

本文关键字:程序集 加载 其他 不能 为什么 | 更新日期: 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提到了LibRepoLib没有对任何其他程序集的引用(它被引用为 dll)。 Repo可能引用也可能没有引用Lib

我得到membershipRepositoryTypenull.我知道也许我需要指定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()