rdlc レポートで複数のサブレポートを処理するための手法を作成しましたが、汎用的で反復可能なものにしようとしたため、代わりにモデルを使用してケースごとに微調整する必要がありました。
たとえば、このような抽象インターフェイスを定義する場合、必要に応じて winform から winform にカット アンド ペーストします。
abstract class ISolutionStrategy
{
public abstract void AlgorithmInterface(Int64 searchCriteria, SubreportProcessingEventArgs e);
}
まず、has-a オブジェクトを含めることで、これを各フォームに取り込めるようにしたいと考えています。また、デリゲートによるディスパッチ処理の動作をカプセル化し、処理メソッドも「汎用」にしたいと考えています。
したがって、設計要件は次のとおりです。
- 複数のサブレポート処理を処理するために winform に含めることができるオブジェクトを作成します
- winform でオブジェクトをインスタンス化して構成する
- winform でディスパッチ テーブルまたは switch/case ステートメントを作成します。
- その winform のレポート ビューアーの特定の要件を処理するすべてのメソッドを渡します。
目標は、スタンドアロンでテストして堅牢にすることができるオブジェクトを作成することです。また、ホイールをカット アンド ペーストして、新しい winform ごとに手動で微調整する必要がないようにすることです。
私が現在持っているものよりも優れたデザインを誰かが見つけたようです。
複数のサブレポート処理を処理するために winform に含めることができるオブジェクトを作成します
これまでのところ、ローカル フォーム ロード イベントにデリゲートがあります。
this.reportViewer1.LocalReport.SubreportProcessing += new SubreportProcessingEventHandler(LocalReport_SubreportProcessing);
*LocalReport_SubreportProcessing* メソッドの switch ステートメントによって処理されます。
メソッドの本体には、switch ステートメントが含まれています。
void LocalReport_SubreportProcessing(object sender, SubreportProcessingEventArgs e)
{
String commonSubreportKey = _commonSubreportKey;
switch (e.ReportPath)
{
case "rptSubAlternateParts":
runSubAlternatePart(e, commonSubreportKey, new GetAlternateParts());
break;
case "rptSubGetAssemblies":
runSubFailurePart(e, commonSubreportKey, new GetAssemblies());
break;
case "rptSubGetAssemblies":
runSubGetGetEndItemLRMFailureInfo(e, commonSubreportKey, new GetEndItemLRMFailureInfo());
break;
case "rptSubGetAssemblies":
runSubGetSubAssemblies(e, commonSubreportKey, new GetSubAssemblies());
break;
default:
break;
}
余談:私の意見では、スイッチは、私が検討した代替案と比較して、ほとんど人間が判読できるものです。レポート名をキー、関数呼び出しデータを値としたハッシュの使用を検討しました。しかし、やり方がよくわからず、他人に理解してもらうのは難しいだろうと思っていました。
その後、switch ステートメントで関数呼び出しから渡された情報を再配置する関数が呼び出されます。
private static void runSubAlternatePart(SubreportProcessingEventArgs e1, String commonReportKey, GetAlternatePart myAP)
{
myAP.AlgorithmInterface(commonReportKey, e1);
}
この再配置は間違いなくコードの吃音ですが、私が実装しようとしている戦略パターンの中間に必要なようです。
abstract class IStrategy
{
public abstract void AlgorithmInterface(String searchParam, SubreportProcessingEventArgs e);
}
レポートの 1 つの戦略の具体的な実装を次に示します。
class GetAlternatePart : IStrategy
{
private BLL.AlternatePartBLL ds = new BLL.AlternatePartBLL();
public override void AlgorithmInterface(String searchParam, SubreportProcessingEventArgs e)
{
e.DataSources.Clear();
DataTable myDataTable = ds.GetAlternativePart(searchParam);
DataSet myDataSet = new DataSet();
myDataSet.Tables.Add(myDataTable);
e.DataSources.Add(new ReportDataSource("BLL_AlternatePartBLL", myDataSet.Tables[0]));
}
}
}
いずれにせよ、複数のサブレポートを持つ多くのレポートがあるため、レポート間で同じロジックを繰り返し手動で配線する必要はありません。
クラスを使用してスタッタリングが発生する中間部分を動的に作成するライブラリ品質の方法が必要です。また、サブレポートと対応するデータ ソースの詳細な接続を実際に実装する「匿名」機能を渡したいと考えています。
サブレポートを含む単一のレポート、またはいくつかの 1 回限りのレポートでさえ、私が行っていることは問題ありませんが、どうすれば手作業を減らし、より堅牢で、よりテストしやすくすることができるでしょうか?
私の環境は、.NET 3.5 をターゲットとする Visual Studio 2008 です。抽象クラスの宣言方法とコンパイル方法に違いがあるようです。