在我的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
所在的程序集。一种方法是在配置中指定程序集名称(如this)。但我认为应该有其他一些方法。否则如何加载其他类只从配置文件中的类名?
例如,MembershipProvider
类可以从其他程序集中正确加载。
我怎么能这样做。或者,如果我不能,为什么我不能?
答案 0 :(得分:2)
来自Type.GetType(String)
的MSDN Library文档:
typeName:要获取的类型的程序集限定名称。见AssemblyQualifiedName。如果类型在当前正在执行的程序集中或在Mscorlib.dll中,则提供由其名称空间限定的类型名称就足够了。
最后一句解释了为什么当你只指定类名时它有时会起作用:如果执行代码在Repo
中,那么只需指定MembershipProvider
即可。但我建议为了清晰(以及性能),您可以避免此行为并始终指定程序集名称。或者,如果您已经引用了包含您的类型的Assembly
,那么您可以改为调用Assembly.GetType
。
尽管如此,如果您确实有一个不知道哪个程序集包含您的类型的方案,那么您可以搜索当前AppDomain中所有已加载的程序集,并尝试在每个程序集上调用Assembly.GetType
:
Type type = AppDomain.CurrentDomain.GetAssemblies()
.Select(assembly => assembly.GetType(typeName))
.First(t => t != null);
答案 1 :(得分:1)
您正在寻找的是这样的:
var types = AppDomain.CurrentDomain.GetAssemblies().ToList()
.SelectMany( s => s.GetTypes() )
.Where( p => p.Name == membershipRepositoryClassName );
实际上这将返回一个列表,因为可以在多个程序集中声明具有相同名称的类型。如果您确定只有一种类型,则可以将.FirstOrDefault()
或.Single()
添加到链的末尾。如果您不确定该类型是否存在,请使用.FirstOrDefault()
,如果不存在,则希望它返回null。如果您确定类型应该存在,请使用.Single()
,并且如果找不到类型,则希望它抛出异常。