ObjectDataSource でのジェネリック クラスの使用
-
09-06-2019 - |
質問
ObjectDataSource で使用したい汎用 Repository<T> クラスがあります。Repository<T> は、DataAccess という別のプロジェクトに存在します。によると MS ニュースグループからのこの投稿 (関連部分を以下にコピー):
内部的には、ObjectDataSourceはType.getType(String)を呼び出してタイプを取得しているため、genericsを使用してタイプを取得する方法のtype.getTypeで文書化されたガイドラインに従う必要があります。Type.GetType の MSDN ライブラリを参照できます。
http://msdn2.microsoft.com/en-us/library/w3f99sx1.aspx
ドキュメントから、genericsを使用しているタイプ名を示すためにバックテック( `)を使用する必要があることがわかります。
また、ここでは型名文字列でアセンブリ名を指定する必要があります。
したがって、あなたの質問に対する答えは、次のように型名を使用することです。
TypeName="TestObjectDataSourceAssembly.MyDataHandler`1[System.String],TestObjectDataSourceAssembly"
わかりました、理にかなっています。ただし、試してみると、ページで例外がスローされます。
<asp:ObjectDataSource ID="MyDataSource" TypeName="MyProject.Repository`1[MyProject.MessageCategory],DataAccess" />
[無効な操作例外:ObjectDataSource 'MyDataSource' の TypeName プロパティで指定された型が見つかりませんでした。]
興味深いのは、これがページを表示しているときにのみ発生することです。VS2008 デザイナーから [データ ソースの構成] ダイアログを開くと、汎用リポジトリ クラスのメソッドが適切に表示されます。デバッグ中に TypeName 文字列を Type.GetType() に渡すと、有効な型も返されます。それで何が与えられるのでしょうか?
解決
このようなことをしてください。
Type type = typeof(Repository<MessageCategory);
string assemblyQualifiedName = type.AssemblyQualifiedName;
AssemblyQualifiedName の値を取得し、それを TypeName フィールドに貼り付けます。Type.GetType(string)、渡される値は次のようにする必要があることに注意してください。
取得する型のアセンブリ修飾名。見る アセンブリ修飾名. 。型が現在実行中のアセンブリまたは 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
他のヒント
これが古い投稿であることは承知していますが、私自身も最近この問題に直面しました。別の解決策は、継承をオブジェクトの構成に置き換えることです。
[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 にリファクタリングを実行させることができます。
ダレン、
ご投稿ありがとうございます。私は一日中これと戦っていました。奇妙なことに、私の場合、角括弧を二重にする必要があります。コード部分の場合:
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
ロジャー