【问题标题】:Using generic classes with ObjectDataSource将泛型类与 ObjectDataSource 一起使用
【发布时间】:2010-09-08 08:30:52
【问题描述】:
我有一个通用的 Repository 类,我想与 ObjectDataSource 一起使用。 Repository 位于一个名为 DataAccess 的单独项目中。根据this post from the MS newsgroups(相关部分复制如下):
在内部,ObjectDataSource 正在调用 Type.GetType(string) 来获取
类型,因此我们需要遵循 Type.GetType 中记录的指南,了解如何
使用泛型获取类型。你可以参考 MSDN Library on Type.GetType:
http://msdn2.microsoft.com/en-us/library/w3f99sx1.aspx
从文档中,您将了解到您需要使用反引号 (`) 来
表示使用泛型的类型名称。
另外,这里我们必须在类型名称字符串中指定程序集名称。
因此,对于您的问题,答案是使用如下类型名称:
TypeName="TestObjectDataSourceAssembly.MyDataHandler`1[System.String],TestObjectDataSourceAssembly"
好的,有道理。但是,当我尝试时,页面会引发异常:
<asp:ObjectDataSource ID="MyDataSource" TypeName="MyProject.Repository`1[MyProject.MessageCategory],DataAccess" />
[InvalidOperationException:找不到在 ObjectDataSource 'MyDataSource' 的 TypeName 属性中指定的类型。]
奇怪的是,这只发生在我查看页面时。当我从 VS2008 设计器打开“配置数据源”对话框时,它正确地向我显示了我的通用存储库类的方法。在调试时将 TypeName 字符串传递给 Type.GetType() 也会返回有效类型。那么是什么给了?
【问题讨论】:
标签:
asp.net
generics
objectdatasource
【解决方案1】:
做这样的事情。
Type type = typeof(Repository<MessageCategory);
string assemblyQualifiedName = type.AssemblyQualifiedName;
获取 assemblyQualifiedName 的值并将其粘贴到 TypeName 字段中。注意Type.GetType(string),传入的值必须是
要获取的类型的程序集限定名称。见AssemblyQualifiedName。如果类型在当前执行的程序集中或 Mscorlib.dll 中,则提供由其命名空间限定的类型名称就足够了。
因此,它可以通过在您的代码中传递该字符串来工作,因为该类在当前执行的程序集中(您正在调用它),而 ObjectDataSource 不在。
您要查找的类型很可能是
MyProject.Repository`1[MyProject.MessageCategory, DataAccess, Version=1.0.0.0, Culture=neutral, PublicKey=null], DataAccess, Version=1.0.0.0, Culture=neutral, PublicKey=null
【解决方案2】:
达伦,
非常非常感谢您的帖子。我整天都在和这个作斗争。奇怪的是,就我而言,我需要将方括号加倍,例如对于您的代码:
MyProject.Repository`1[[MyProject.MessageCategory, DataAccess, Version=1.0.0.0, Culture=neutral, PublicKey=null]], DataAccess, Version=1.0.0.0, Culture=neutral, PublicKey=null
罗杰
【解决方案3】:
我知道这是一篇旧帖子,但我最近自己也遇到了这个问题。另一种解决方案是用对象组合替换继承,例如
[DataObject]
public class DataAccessObject {
private Repository<MessageCategory> _repository;
// ctor omitted for clarity
// ...
[DataObjectMethod(DataObjectMethodType.Select)]
public MessageCategory Get(int key) {
return _repository.Get(key);
}
}
这样,ObjectDataSource 不知道存储库,因为它隐藏在类中。我的外观层中有一个类库,这是一个非常合理的地方,可以将此代码放入我正在处理的项目中。
另外,如果你使用 Resharper 和接口,可以让 Resharper 使用 Resharper 的“使用字段实现”功能进行重构。