List<ICalculation>
アプリケーションで事前定義されたすべての計算のリポジトリとして機能するジェネリックがあるとしましょう...
ICalculation<T, U>
より基本的な を実装するという汎用インターフェイスがありますICalculation
。
public interface ICalculation
{
string Identifier { get; }
object Calculate(object inputData);
}
public interface ICalculation<in TIn, out TOut> : ICalculation
{
string Identifier { get; }
TOut Calculate(TIn inputData)
}
このインターフェイスを実装する抽象クラス CalculationBase もあります
public abstract class CalculationBase<TIn, TOut> : ICalculation<in TIn, out TOut>, ICalculation
{
public abstract string Identifier { get; }
public abstract Func<TIn, TOut> Calculation { get; }
public virtual TOut Calculate(TIn inputData)
{
return Calculate(inputData, Calculation);
}
virtual object ICalculation.Calculate(object inputData)
{
return (TOut)calculation((TIn)inputData);
}
public static TOut Calculate(TIn inputData, Func<TIn, TOut> calculation)
{
if (calculation == null || inputData == null)
return default(TOut);
return calculation(inputData);
}
}
だから、今、私はいくつかの入力に対して機能するCalculationBaseを実装する計算をたくさん持っています... 1つの例:
public sealed class NumberOfBillableInvoices : CalculationBase<IClientAccount, int>
{
public override string identifier { get { return "@BillableInvoiceCount"; } }
public override Func<IClientAccount, int> Calculation
{
get { return inputData => inputData.Invoices.Count(i => i.IsBillable); }
}
}
各計算は特定のタイプのオブジェクトを対象としており、計算の性質に応じて異なる出力を返します。例: 通貨の計算では小数が返される場合があり、カウンターでは整数または長整数などが返される可能性があります。
私は、アプリケーションのロード時にそれ自体をロードする計算リポジトリを持っています。数式を評価する必要がある場合、計算エンジンはクエリ対象のオブジェクトを取得します。この例では、型の具体的なインスタンスがIClientAccount
あり、それに対していくつかの数式を評価したいと考えています"Math.Max(@BillableInvoiceCount - 5, 0) * $1.20"
。エンジンは、TIn が IClientAccount 型であるすべての計算を実行して取得し、その計算を式で見つかったトークン (つまり@BillableInvoiceCount
) と照合します。次に、NCalc、FLEE、または別の計算エンジンなどの計算エンジンが最終的な方程式を評価します。
したがって、私の問題は、正しいトークンを探してすべての計算を反復処理したくないということです。現実的には、トークンが複数のオブジェクト タイプにまたがる場合、トークンが衝突する可能性があります。たとえば、同じトークンを使用して、異なるコンテキストで異なることを意味する場合があります。リポジトリ内の計算を、TIn が計算しようとしているオブジェクト タイプと一致するものだけに絞り込むことができれば、より簡単になります。
この時点でいくつかの考えがあります -
1)。オブジェクトの TIn 部分のみをマーシャリングするリポジトリを作成できますか? これに対する答えはおそらくノーだと思います...しかし、それが可能である可能性がある場合、これを実装する方法の最初の手がかりがありません-誰かにアイデアはありますか?
2)。TIn がクエリ対象のオブジェクトのタイプと一致するすべての計算についてリポジトリにクエリを実行する方法はありますか? もしそうなら、どのように?
3)。計算対象の TIn/TOut のすべての組み合わせに基づいて、複数のリポジトリがありますか? もしそうなら、クエリを実行しているオブジェクトと正しいリポジトリを結合するにはどうすればよいですか? 私はまだTIn部分のみに基づいてリポジトリを照合しようとしているため...
4)。すべての計算で異なる型を返すのではなく double を返すようにすると、リポジトリを入力型だけに型付けして単純にすることができます...しかし、これは単純ですが、意味的には間違っているように感じます。
考え?
事前に乾杯:)