2

web.config我的 MVC 项目中,我有这个:

<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 应用程序web.config在 assembly 中Web。我给出的代码段是在汇编中Lib。该课程MembershipRepository正在组装中RepoWeb参考了LibRepoLib没有对任何其他程序集的引用(它可能被引用为 dll)。 Repo可能有也可能没有参考Lib

我明白membershipRepositoryTypenull。我知道也许我需要指定其中的程序集MembershipRepository。一种方法是在配置中指定程序集名称(像这样)。但我认为应该有一些其他的方式。否则如何加载其他类仅从配置文件中获取类名?例如,MembershipProvider类从其他程序集中加载得很好。

我怎么能这样做。或者如果我不能,为什么我不能?

4

2 回答 2

2

来自 MSDN Library 文档Type.GetType(String)

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);
于 2012-06-17T16:19:21.120 回答
1

你正在寻找的是这样的:

var types = AppDomain.CurrentDomain.GetAssemblies().ToList()
    .SelectMany( s => s.GetTypes() )
    .Where( p => p.Name == membershipRepositoryClassName );

这实际上将返回一个列表,因为可以在多个程序集中声明具有相同名称的类型。如果您确定只有一种类型,则可以将.FirstOrDefault()或添加.Single()到链的末尾。如果.FirstOrDefault()您不确定类型是否存在并且希望它在不存在时返回 null,请使用此选项。如果.Single()您确定类型应该存在并且希望它在找不到类型时抛出异常,请使用。

于 2012-06-17T15:52:56.303 回答