Настройте MassTransit для десериализации полиморфных свойств.C#

Место общения программистов C#
Ответить
Anonymous
 Настройте MassTransit для десериализации полиморфных свойств.

Сообщение Anonymous »

Итак, мы отправляем сообщение, состоящее из сложного типа домена. Наши потребители не срабатывают, потому что MassTransit не может десериализовать сообщение и делегировать его потребителю.

Этот сценарий можно продемонстрировать с помощью

Код: Выделить всё

// message interface
public interface ITestMessage { TestBaseClass Data { get; set; } };

// message implementation
public class TestMessage : ITestMessage
{
public TestBaseClass Data { get; set; }
}

// abstract child
public abstract class TestBaseClass { }

// a concrete implementation of abstract child, cannot be deserialized
// by default serializer configuration
public class TestConcreteClass : TestBaseClass { }

// simple consumer, uses a reset-event to synchronize with calling
// test method
public class TestConsumer : IConsumer
{
private readonly Action action = null;
public TestConsumer(Action action) { this.action = action; }
public Task Consume(ConsumeContext context)
{
action();
return context.CompleteTask;
}
}

[TestMethod]
public void Publish_WhenPolymorphicMessage_ConsumesMessage()
{
ManualResetEvent isConsumed = new ManualResetEvent(false);
IBusControl bus = Bus.Factory.CreateUsingInMemory(c =>
{
InMemoryTransportCache inMemoryTransportCache =
new InMemoryTransportCache(Environment.ProcessorCount);
c.SetTransportProvider(inMemoryTransportCache);
c.ReceiveEndpoint(
"",
e => e.Consumer(
() => new TestConsumer(() => isConsumed.Set())));
});
bus.Start();

ITestMessage message = new TestMessage
{
// comment out assignment below, et voila, we pass :S
Data = new TestConcreteClass { },
};

// attempt to publish message and wait for consumer
bus.Publish(message);

// simple timeout fails
Assert.IsTrue(isConsumed.WaitOne(TimeSpan.FromSeconds(5)));
}
Конечно, мы можем успешно продемонстрировать, что сообщение с полиморфным дочерним элементом может быть сериализовано

Код: Выделить всё

[TestMethod]
public void Serialize_WithPolymorphicChild_DeserializesCorrectly()
{
ITestMessage message = new TestMessage { Data = new TestConcreteClass { }, };
JsonSerializerSettings settings =
new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All, };
string messageString = JsonConvert.SerializeObject(message, settings);
ITestMessage messageDeserialized = (ITestMessage)(JsonConvert.DeserializeObject(
messageString,
settings));

Assert.IsNotNull(messageDeserialized);
Assert.IsNotNull(messageDeserialized.Data);
Assert.IsInstanceOfType(messageDeserialized.Data, typeof(TestConcreteClass));
Assert.AreNotSame(message.Data, messageDeserialized.Data);
}
Я пробовал различные конфигурации, но безрезультатно.

Код: Выделить всё

IBusControl bus = Bus.Factory.CreateUsingInMemory(c =>
{
InMemoryTransportCache inMemoryTransportCache =
new InMemoryTransportCache(Environment.ProcessorCount);
c.SetTransportProvider(inMemoryTransportCache);

// attempt to set and configure json serializer; zero effect
c.ConfigureJsonDeserializer(
s =>
{
s.TypeNameHandling = TypeNameHandling.All;
return s;
});
c.ConfigureJsonSerializer(
s =>
{
s.TypeNameHandling = TypeNameHandling.All;
return s;
});
c.UseJsonSerializer();

c.ReceiveEndpoint(
"",
e => e.Consumer(
() => new TestConsumer(() => isConsumed.Set())));
});
Я ищу любое успешное решение, например, украшение классов сообщений/доменов атрибутами KnownType или конфигурацию шины. Все, что приводит к успешному прохождению метода тестирования, описанного выше.

Подробнее здесь: https://stackoverflow.com/questions/340 ... properties
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»