1

NHibernate も使用するプロジェクトに MassTransit を組み込もうとしています。NHibernate では、保護された内部可視性を持つデフォルトのコンストラクターが少なくとも必要です。

次の問題に遭遇します。メッセージは問題なく発行できますが、ハンドラは初期化されていないメンバーを持つメッセージ オブジェクトを受け取ります。MassTransit ソースのデバッグと検査をしばらく行った後、これは、MassTransit が逆シリアル化中に ConstructorHandling.AllowNonPublicDefaultConstructor の設定を使用することが原因であることがわかりました。これにより、保護された内部デフォルト コンストラクターが、パラメーター化されたコンストラクターの代わりに呼び出されます。この動作を再現することができました。以下のコードを参照してください。

MassTransit が AllowNonPublicDefaultConstructor を使用する理由は何ですか? また、この動作を変更する方法はありますか?

class Program
{
    public class TestClass
    {
        private readonly string _someString;

        public string SomeString {
            get { return _someString; }
        }

        public TestClass(string someString)
        {
            _someString = someString;
        }

        protected internal TestClass()
        {
            _someString = "uninitialized";
        }
    }

    static void Main(string[] args)
    {
        var obj = new TestClass("Hello World");

        var serializerSettings = new JsonSerializerSettings
                {
                    ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor,
                    ContractResolver = new ... // MassTransit contract resolver that includes private setters
                };


        string serializedObject = JsonConvert.SerializeObject(obj, serializerSettings);

        var deserializedObj = JsonConvert.DeserializeObject<TestClass>(serializedObject, serializerSettings);

        // deserializedObj.SomeString == "uninitialized"
    }
}
4

1 に答える 1

1

メッセージには、ロジックがまったく含まれていてはなりません。メッセージは契約です。それらのロジックは、何度も何度もあなたを噛むだけになります。:( 常にデフォルトのパラメーターなしのコンストラクターを使用します。コンストラクターがない場合、メッセージは逆シリアル化されません。

メッセージ型からのロジックの削除を強制するために、具象型ではなくインターフェイスを常に使用することをお勧めします。しかし、本当にこの動作が必要な場合は、独自のシリアライザーを作成する必要があります。

さらに議論したい場合は、メーリング リストに参加することをお勧めします: groups.google.com/group/masstransit-discuss。

于 2013-11-13T13:26:46.230 に答える