2012-06-17 67 views
2

在我的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在组装RepoWeb提及LibRepoLib没有引用任何其他程序集(它可能被引用为dll)。 Repo可能会或可能不会参考Lib。我得到membershipRepositoryTypenull。我明白,也许我需要指定MembershipRepository所在的程序集。一种方法是在配置中指定程序集名称(如this)。但我认为应该有其他方法。否则,如何加载其他类只从配置文件中创建类名? 例如,MembershipProvider类从其他程序集加载得很好。

我该怎么办。或者如果我不能,为什么我不能?

+1

故障排除提示:将'true'传递给'Type.GetType'''Type.GetType(membershipRepositoryClassName,true)''''''这样你就得到了一个描述问题的详细异常。 –

回答

2

从MSDN库文档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); 
+0

谢谢,这解释了一切。我应该在配置中指定程序集。当然,从所有程序集中获取_most probable_类型并不是一个好主意。我只是想实现**为什么我需要指定程序集时,其他人不需要**。现在我意识到,我以前的一些配置只是幸运地工作! – Mohayemin

+0

重新检查配置,如果程序集在当前项目中被引用,它看起来像我不需要指定程序集。是这样吗? – Mohayemin

+0

据我所知,不,事实并非如此。例如,即使您的项目可能引用System.dll,“Type.GetType(”System.Uri“)将始终返回null。 –

1

你要找什么是这样的:

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

,实际上是要返回一个列表,因为具有相同名称的类型可能在不止一个组件来声明。如果您确定只有一种类型,则可以在链的末尾添加.FirstOrDefault().Single()。如果您不确定该类型是否存在,并且希望在不存在的情况下返回null,请使用.FirstOrDefault()。如果您确定该类型应该存在并且希望它在未找到类型时引发异常,请使用.Single()

相关问题