1

既存の asp.net (c#) アプリケーションがあります。雇用日と登録日を指定して有効日を計算する柔軟なルールを作成する方法をユーザーに提供する必要があります。

使用できるルールの例:

  1. 採用日または入学日のいずれか遅い方
  2. 雇用日 + 90 日
  3. 入会日の翌月1日
  4. 入会日が15日以前の場合は、翌月1日が有効日となります。15日以降であれば翌月1日です。

最初はいくつかのオフセット フィールド (日のオフセット、月のオフセットなど) から始めましたが、新しい要件に遭遇するにつれて、現在のアプローチでは十分な柔軟性がないことがわかりました。

私がやりたいことは、エンド ユーザーが 2 つのパラメーター (hiredate、enrollmentdate) を指定して日付を返す関数を定義し、その関数をデータベースに格納できるようにすることです。有効日を計算する必要がある場合は、この関数をデータベースから取り出して実行し、パラメータを渡して有効日を取得します。

私の最初の反応は、日付操作関数を定義してソリューションに統合できるようにする DSL を探すことでした。しかし、適切な DSL を探しても何も見つかりませんでした。

CSharpCodeProvider がソリューションのコンポーネントとして機能するかどうか疑問に思っています。データベースから文字列を取り出し、CsharpCodeProvider を介してコンパイルした場合、結果のコードが関数シグネチャと一致するように強制できますか (2 つの datetime パラメーターを取り、datatime を返します)。

関数に副作用がないことを確認する方法はありますか? たとえば、I/O なし。読み取り、セッション、キャッシュ、またはアプリケーションはありません。

4

2 に答える 2

2

ここで私の最近の回答を参照してください: Parsing "DateTime.Now"?

基本的に、 FLEEなどの既存のライブラリを簡単に活用して、式を解析し、これらのルールの IL を出力できます。例を見ると、利用するユーザー式の変数を設定する方法がわかります。たとえば、いくつかの入力変数 (HireDateまたは などEnrollmentDate) と、日付を返すユーザー式/述語で構成される「ルール」を定義できます。リンクされた回答にあるようなメンバーを公開するDateTimeと、ユーザーはそれらも活用できます。

簡単な例として、テストされていませんが、アイデアが得られるはずです。

月の最初の日を取得するなど、いくつかのカスタム関数をセットアップして役立てることができます。

public static class CustomFunctions
{
    public static DateTime GetFirstDayOfMonth(DateTime date)
    {
        return new DateTime(date.Year, date.Month, 1);
    }
}

基本的な FLEE セットアップ (必要に応じてカスタマイズ/微調整する必要があります)

ExpressionContext context = new ExpressionContext();

//Tell FLEE to expect a DateTime result; if the expression evaluates otherwise, 
//throws an ExpressionCompileException when compiling the expression
context.Options.ResultType = typeof(DateTime);

//Instruct FLEE to expose the `DateTime` static members and have 
//them accessible via "DateTime".
//This mimics the same exact C# syntax to access `DateTime.Now`
context.Imports.AddType(typeof(DateTime), "DateTime");
context.Imports.AddType(typeof(CustomFunctions));

//Expose your key variables like HireDate and EnrollmentDate
context.Variables["HireDate"] = GetHireDate(); //DateTime I suppose
context.Variables["EnrollmentDate"] = GetEnrollmentDate(); //DateTime I suppose

//Parse the expression, naturally the string would come from your data source
IGenericExpression<DateTime> expression = context.CompileGeneric<DateTime>(GetYourRule(), context);

DateTime date = expression.Evaluate();

次に、ルールは次のようになります。

string rule1 = "if(HireDate > EnrollmentDate, HireDate, EnrollmentDate)";
string rule2 = "HireDate.AddDays(90)";
string rule3 = "GetFirstDayOfMonth(EnrollmentDate.AddMonths(1))";
string rule4 = "GetFirstDayOfMonth(EnrollmentDate.AddMonths(if(EnrollmentDate.Day < 15, 1, 2)))"; 
于 2013-02-06T13:39:03.013 に答える