1

我正在尝试将 MassTransit 合并到一个也使用 NHibernate 的项目中。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 回答