2

私のチームは、カスタム アセンブリ全体で一元化された定数 (おそらく読み取り専用の静的変数) を管理する最善の方法を見つけようとしています。アセンブリがランタイムに動的に読み込まれる処理アーキテクチャを構築しました。データがシステムを通過するときに、一部のアセンブリが情報をディクショナリに書き込みます。この情報は、データを読み取って処理する別のアセンブリに渡されます。当社の製品が成熟し、お客様がさまざまな処理機能を必要とするようになると、書き込み/読み取りを行う新しいデータ フィールドを追加する必要があります。現在、コア dll で定数を定義していますが、新しいデータを取得したときにコア dll を再コンパイルする必要があるため、これは長期的には機能しません。その際、テスト チームは、新しいアセンブリによって提供される新しい機能をテストするだけでなく、アプリケーション全体を完全に回帰テストする必要があります。新しい定数を追加し、絶対に必要ではないものを再コンパイル/デプロイすることなく、どのデータが書き込まれているのかを知る方法を見つけようとしていました。

次の 2 つのオプションを検討しました。

  1. 定数のみを保持する定数 dll を作成します。新しいフィールドが必要な場合は、それらを dll に追加します (決して削除しないでください)。これの欠点は、dll への変更がシステム全体に影響を与えることです。そのため、完全な回帰テストが必要になる場合があります。

  2. 各アセンブリで読み取り/書き込みを行うすべてのフィールドを公開し、開発者の統合中に名前の不一致を探します。たとえば、Assembly1 が (Field1、Field2) を書き込み、Assembly2 が (field1、Field2) を読み取ると、ディクショナリ キーの大文字と小文字が区別されるため、(Field1 と field1) の不一致が生じます。これにより、定数アセンブリを使用できなくなりますが、不一致を検証するために追加のコードが必要になり、多少の結合が発生するようです。

注: 定数と言うとき、実際には定数を意味するわけではありません。最終的に使用するソリューションによっては、読み取り専用の静的を使用する可能性があります。

誰かがこのようなことをしたことがある場合、またはこれを達成する方法について何か考えがある場合は、ご意見をお待ちしております. 私たちの根本的な目的は、新しいアセンブリを展開するだけで新しい機能を提供できるようにすることです。

4

2 に答える 2

0

あなたのコメントに基づいて、これは本当に DTO クラスを使用する必要があるように思えます。値を持つ辞書ではなく

dict["PrimaryAddress"] = "123 Someroad St."; 
dict["Name"] = "John Doe";`

あなたはオブジェクトを持っている必要があります

public class Address
{
    public string PrimaryAddress { get; set; }
    public string Name { get; set; }
}
....
new Address { 
    PrimaryAddress = "123 Someroad St.",
    Name = "John Doe",
};

便宜上、すべてのクラスの標準的な動作を定義するコア ライブラリに基本クラスを作成し (たとえば、public Dictionary<string, string> ConvertToDictionary()従来の使用のために)、各アセンブリがそれを継承して独自のオブジェクトを作成することができます。次に、それらを使用するアセンブリは、生成アセンブリを参照してそれを特定の型として扱うか、単にそれを基本フォームとして扱い、基本機能を使用することができます。

于 2012-11-14T15:41:06.770 に答える
0

できることは、プロセス全体で他のすべてのアセンブリによって参照される 1 つのアセンブリを作成することです。(アプリケーションには実際には 1 つのプロセスしかないと仮定していることに注意してください)。このアセンブリは、これらの「定数」を保持するクラスを公開します。それをセッションと呼びましょう。以下は、プロジェクトの 1 つで使用する実装です。

//Defined in Dll appshared.dll    
public static class MyApplication
{
    static AppSession appSession = new AppSession();
    public interface IAppSession
    {
        Object this[string key]
        {
            get;
            set;
        }
    };
    sealed class AppSession : IAppSession
    {

        Dictionary<String, Object> _session = new Dictionary<string, object>();
        public AppSession()
        {
        }
        public Object this[string key]
        {
            get
            {
                Object ret = null;
                lock (_session)
                {
                    _session.TryGetValue(key, out ret);
                }
                return ret;
            }
            set
            {
                if (key == null)
                    throw new ArgumentNullException();
                try
                {
                    lock (_session)
                    {
                        if (value != null)
                            _session[key] = value;
                        else
                            _session.Remove(key);
                    }
                }
                catch (Exception eX)
                {
                }
            }
        }
    };

    public static IAppSession Session
    {
        get
        {
            return appSession;
        }
    }

};

そして、次のように使用できます。

//In Dll A referencing appshared.dll   
MyApplication.Session["Const1"] = 1.0;//Set a global value

//In Dll B referencing appshared.dll    
double const1 = (double)MyApplication["Const1"];//Read a global value - const1 will have the value set by Dll A

//In Dll C referencing appshared.dll
MyApplication.Session["Const1"] = null;//Delete a global value;

もちろん、必要なあらゆる種類のデータを保存できます。大文字と小文字を区別しないように簡単に変更できます。

また、値を構成ファイルと同期できる、より複雑なセッション オブジェクトもあるため、「定数」は実行間で保存されます。ただし、そのような機能が必要であるとは言わなかったので、この単純なクラスは問題なく機能するはずです。

于 2012-11-14T16:26:59.737 に答える