关于 asp.net:将泛型类与 ObjectDataSource 一起使用

关于 asp.net:将泛型类与 ObjectDataSource 一起使用

Using generic classes with ObjectDataSource

我有一个通用的 RepositoryT 类,我想与 ObjectDataSource 一起使用。 RepositoryT 位于一个名为 DataAccess 的单独项目中。根据 MS 新闻组的这篇帖子(相关部分复制如下):

Internally, the ObjectDataSource is calling Type.GetType(string) to get the
type, so we need to follow the guideline documented in Type.GetType on how
to get type using generics. You can refer to MSDN Library on Type.GetType:

http://msdn2.microsoft.com/en-us/library/w3f99sx1.aspx

From the document, you will learn that you need to use backtick (`) to
denotes the type name which is using generics.

Also, here we must specify the assembly name in the type name string.

So, for your question, the answer is to use type name like follows:

TypeName="TestObjectDataSourceAssembly.MyDataHandler`1[System.String],TestObjectDataSourceAssembly"

好的,有道理。但是,当我尝试时,页面会引发异常:

1
asp:ObjectDataSource ID="MyDataSource" TypeName="MyProject.Repository`1[MyProject.MessageCategory],DataAccess" /

[InvalidOperationException: The type specified in the TypeName property of ObjectDataSource 'MyDataSource' could not be found.]

奇怪的是,这只发生在我查看页面时。当我从 VS2008 设计器打开"配置数据源"对话框时,它正确地向我显示了我的通用存储库类的方法。在调试时将 TypeName 字符串传递给 Type.GetType() 也会返回有效类型。那么是什么给出的呢?


做这样的事情。

1
2
Type type = typeof(RepositoryMessageCategory);
string assemblyQualifiedName = type.AssemblyQualifiedName;

获取 assemblyQualifiedName 的值并将其粘贴到 TypeName 字段中。注意Type.GetType(string),传入的值必须是

The assembly-qualified name of the type to get. See AssemblyQualifiedName. If the type is in the currently executing assembly or in Mscorlib.dll, it is sufficient to supply the type name qualified by its namespace.

因此,它可以通过在您的代码中传递该字符串来工作,因为该类在当前执行的程序集中(您正在调用它),而 ObjectDataSource 不在。

您要查找的类型很可能是

1
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

我知道这是一篇旧帖子,但我最近自己也遇到了这个问题。另一种解决方案是用对象组合替换继承,例如

1
2
3
4
5
6
7
8
9
10
11
12
[DataObject]
public class DataAccessObject {
    private RepositoryMessageCategory _repository;

    // ctor omitted for clarity
    // ...

    [DataObjectMethod(DataObjectMethodType.Select)]
    public MessageCategory Get(int key) {
        return _repository.Get(key);
    }
}

这样,ObjectDataSource 不知道存储库,因为它隐藏在类中。我的外观层中有一个类库,这是一个非常合理的地方,可以将此代码放入我正在处理的项目中。

另外,如果你正在使用 Resharper 和接口,可以让 Resharper 使用 Resharper 的"使用字段实现"功能进行重构。


达伦,

非常非常感谢您的帖子。我整天都在和这个作斗争。奇怪的是,就我而言,我需要将方括号加倍,例如对于您的代码:

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

罗杰


推荐阅读