5

バックグラウンド

Linq to SQL を使用しているため、自動生成されたクラスを含む生成された DBML ファイルがあります。生成プロセスの一部では、特定のアクションの部分的なメソッドが作成されます。私の場合、関心のある 2 つのメソッドは、テーブル レコードの挿入と更新に関連しています。これらの部分メソッドは、DBML デザイナーで作成された各テーブルごとに生成されます。次に例を示します。

partial void InsertMyTable(MyTable instance);
partial void UpdateMyTable(MyTable instance);

現在、私のアプリケーションの設計の一部では、これら 2 つの部分メソッドがすべてのテーブルに対して常に実装されている必要があります。(これらは基本的に、挿入/更新されるレコードにタイムスタンプを追加するために使用されます)。

要件

私は単体テスト プロジェクトを持っています。これは一般的な方法ではないかもしれませんが、特定のことが適切に実装されていることを確認するいくつかのテストを含めたいと考えています。この場合、開発者が上記の部分的なメソッドを実装することを覚えていることを確認したいと思います (実際の実装については気にしません。実装されていることだけを気にします)。

問題

私がする必要があるのは、リフレクションを使用して各部分メソッドが実装されているかどうかを確認することですが、それを判断する方法がわかりません。

試みられた努力

これまでのところ、データ コンテキスト内に含まれるメソッドのリストを取得することができました。それを、各テーブルに期待されるメソッドと比較することができます。問題は、特定の部分メソッドに実際に実装があるかどうかを判断する方法が見つからないことです。

var methods = (typeof(MyDataContext)).GetMethods(BindingFlags.NonPublic | BindingFlags.Instance);
foreach (var method in methods) 
{
    Console.WriteLine(method.Name);
    //how to check if method is implemented, or just an unimplemented partial
}
4

3 に答える 3

11

あなたがすでに持っているものは機能します。partialメソッドに実装がない場合は、まったく存在しません。反射によって偶然見つけられる可能性のある「宣言スタブ」はありません。部分メソッドに実装があるか、コンパイラによって完全に削除されています。

GetMethodつまり、基本的に: /を使用してメソッドが見つからない場合GetMethods(質問に従って適切なBindingFlagsを使用)、実装されていません。

于 2013-11-13T13:18:53.300 に答える
2

別のアイデアとして (およびコンパイル時に明らかであり、難読化の問題の影響を受けにくいもの):

// generated code
public partial class Whatever : ISomeInterface<MyTable>
{
    //...
}

//somewhere else
public interface ISomeInterface<T>
{
    void Insert(T instance);
    void Update(T instance);
}

これで、コンパイラは、おそらく部分クラスで、このインターフェイスを完全に実装しないと、ユーザーが先に進めなくなります。

partial class Whatever
{
    public void Insert(MyTable instance) {...}
    public void Update(MyTable instance) {...}
}

(明示的なインターフェース実装を引き続き使用できることに注意してください。ただし、データにアクセスするときは、そのインターフェースを自分で使用する必要があります。これ以上のリフレクションは避けてください)

于 2013-11-13T13:26:40.267 に答える
0

同じ問題に遭遇したとき、次のように解決しました。

var Method = (typeof(Entities))
.GetMethods(System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance)
.FirstOrDefault(x => x.Name == "SomeMethodShouldBeOnPartialClass");
if (Method != null) Method.Invoke(this,null);
于 2015-06-23T07:23:15.993 に答える