0

私は現在、オブジェクト変更ログ機能の作業を終えており、いくつかの点を改善したいと考えています。履歴データが表示される Web フォーム/レポートが多数あるため、コントロール/レポートを変更せずにそれを実装する方法があるかどうか疑問に思っています。現在、私はこのような状況にあります:

public class Foo {
    public string Property1 { get; set; }
    public DateTime CreatedDate { get; set;}

    public string GetHistoricalValue(string propertyName) 
    {
        HistoryHelper historyHelper = CreateHistoryHelper(this);
        return historyHelper.GetHistoricalValue(propertyName, CreatedDate);
    }
...

public class HistoryHelper {
    public string GetHistoricalValue(string propertyName, DateTime date) {
    ...

したがって、だれかが Property1 の履歴データを取得したい場合:

string historicalValue = fooInstance.GetHistoricalValue("Property1");

このアプローチでは、現在のアプリケーションに多くの変更が必要であることは明らかです。通常の方法で Property1 にアクセスするときに Foo クラスが履歴値を返すようにする方法はありますか:

string historicalValue = fooInstance.Property1;

オーバーライドされたプロパティまたはその他のソリューションを使用してサブクラスを動的に生成するようなものですか?
これは可能ですか?

4

2 に答える 2

1

最初の答え

このようなもの:

public class Foo {
    public bool HistoricalMode { get; set; }

    private string _property1;
    public string Property1 { 
        get { 
            if (HistoricalMode) {
                return GetHistoricalValue("Property1");
            } else {
                return _property1;
            }
        set {
            if (HistoricalMode){
                throw new NotSupportedException("Updates not possible in historical mode.");
            } else {
                _property1 = value;
            }
        }
    }
    public DateTime CreatedDate { 
        get {
            // Similar pattern as above
        }
        set {
            // Similar pattern as above
        }
    }

    public string GetHistoricalValue(string propertyName) {
        HistoryHelper historyHelper = CreateHistoryHelper(this);
        return historyHelper.GetHistoricalValue(propertyName, CreatedDate);
    }
}

基本的には、オブジェクトが「履歴モード」であることを示すブール値をオブジェクトに保持するという考え方です。その場合は、ヘルパー メソッドを使用してください。そうでない場合は、通常のプロパティの getter/setter が適用されます。

アップデート

この質問を解決するには、フレームワークを変更する必要があると思います (すべてのアプリケーションに対して単一のフレームワークを使用している場合)。オブジェクトをロードする方法で解決策を探します。オブジェクトが「履歴モード」で必要な場合と「通常モード」で必要な場合を検出できることを願っています。データベースからオブジェクト (レコード) を「読み取るだけ」の場合、履歴モードでは、変更ログ機能から元のオブジェクト (変更が発生した時点から) を作成する必要があります。そうすれば、現在のすべてのアプリケーションを (うまくいけば) そのままにしておくことができます。あなたがする必要がある「唯一の」変更は、リポジトリクラスにあります。

これはすべて憶測です。

于 2012-11-15T13:19:29.597 に答える
0

Fooインスタンスの作成方法に簡単に影響を与えることができますか?その場合、たとえば、派生を作成しclass HistoricalFoo : FooProperty1仮想を作成し、そのゲッターを使用して動作を変更できます。その後、HistoricalFoo履歴データが必要なときにいつでも使用できます。これはあまりクリーンなオブジェクトモデルではありませんが、仕事を成し遂げることはできます。

public class Foo
{
    protected string _property1;
    public virtual string Property1
    {
        get { return _property1; }
        set { _property1 = value; }
    }

    public DateTime CreatedDate { get; set;}

    /* ... */
}

public class HistoricalFoo : Foo
{
    public override string Property1
    {
        get
        {
            return GetHistoricalValue("Property1");
        }
    }
}

これが当てはまらない場合は、いくつかの決定ロジックをProperty1ゲッターに埋め込むことができます。このシナリオでは、Fooインスタンスの内部状態を変更する必要があります。たとえば、ブールフラグを設定しますIsInHistoryMode。ただし、特にマルチスレッド環境では、オブジェクトの状態を変更するのは非常に難しい場合があります。

public class Foo
{
    public bool IsInHistoryMode { get; set; }

    protected string _property1;
    public virtual string Property1
    {
        get
        {
            if(IsInHistoryMode)
            {
                return GetHistoricalValue("Property1");
            }

            return _property1;
        }
        set
        {
            _property1 = value;
        }
    }

    public DateTime CreatedDate { get; set;}

    /* ... */
}
于 2012-11-15T13:16:37.380 に答える