BrokeredMessage发送/解析消息Serialize POCO

时间:2013-03-15 23:17:48

标签: .net azureservicebus

我正在注册收到呼叫特定事件时的特定消息。

我看到BrokeredMessage接受了一个对象,据我所知,我需要为所有消息实现ISerializable。

Hpwever,我的消息是普通的POCO对象,我想探索按原样使用它们的可能性:

public class CustomerOrderEvent
{
   int orderId;
   int quantity;
   double value;
}

在接收期间,我会:

  1. 检索邮件并返回对象类型
  2. 查看我的地图,呼叫已注册此活动消息的活动
  3. 虽然描述简单,但第一步就把头发拉了出来。

    是否有任何框架可以通过Azure总线为我包装?

    如果使用IoC,理想情况下我希望能够使用我最喜欢的注入器SimpleInjector - 如果直接定义适配器,这不会有问题。

1 个答案:

答案 0 :(得分:3)

在某些时候,您必须拥有一个包含DataContractDataMember等类的属性,并将其发送到DataContactSerializer。但是,您不必将它们添加到您的POCO中。

一种选择是简单地创建一个使用与POCO相同的数据填充的DTO。这个DTO你用BrokeredMessage包裹。或者,您只需将POCO以某种方式序列化为Stream并将其提交给BrokeredMessage

另一种方法是使用.NET序列化调用"代理" (与DTO大致相同)。这要求您不仅要定义代理,还要定义在手动创建IDataContractSurrogate时要使用的DataContractSerializer实现。

首先,我假设您真正拥有的是具有公共属性的POCO,而不是您发布的私有字段的POCO。有了它,你可以创建一个代理:

[DataContract(Name = "CustomerOrderEvent", Namespace = "http://www.mynamespace.com")]
public class CustomerOrderEventSurrogate
{
    [DataMember]
    public int OrderId { get; set; }

    [DataMember]
    public int Quantity { get; set; }

    [DataMember]
    public double Value { get; set; }
}

...直截了当,在这个例子中,与你的POCO相同,具有所有必要的属性。然后定义IDataContractSurrogate实现:

public class DataContractSurrogate : IDataContractSurrogate
{
    public Type GetDataContractType(Type type)
    {
        if (typeof (CustomerOrderEvent).IsAssignableFrom(type))
        {
            return typeof (CustomerOrderEventSurrogate);
        }
        return type;
    }

    public object GetObjectToSerialize(object obj, Type targetType)
    {
        var customerOrderEvent = obj as CustomerOrderEvent;
        if (customerOrderEvent == null) return obj;

        var surrogate =
            new CustomerOrderEventSurrogate
                {
                    OrderId = customerOrderEvent.OrderId,
                    Quantity = customerOrderEvent.Quantity,
                    Value = customerOrderEvent.Value
                };
        return surrogate;
    }

    public object GetDeserializedObject(object obj, Type targetType)
    {
        var surrogate = obj as CustomerOrderEventSurrogate;
        if (surrogate == null) return obj;

        var customerOrderEvent =
            new CustomerOrderEvent()
                {
                    OrderId = surrogate.OrderId,
                    Quantity = surrogate.Quantity,
                    Value = surrogate.Value
                };
        return customerOrderEvent;
    }

    public object GetCustomDataToExport(MemberInfo memberInfo, Type dataContractType)
    {
        throw new NotImplementedException();
    }

    public object GetCustomDataToExport(Type clrType, Type dataContractType)
    {
        throw new NotImplementedException();
    }

    public void GetKnownCustomDataTypes(Collection<Type> customDataTypes)
    {
        throw new NotImplementedException();
    }

    public Type GetReferencedTypeOnImport(string typeName, string typeNamespace, object customData)
    {
        throw new NotImplementedException();
    }

    public CodeTypeDeclaration ProcessImportedType(CodeTypeDeclaration typeDeclaration, CodeCompileUnit compileUnit)
    {
        throw new NotImplementedException();
    }
}

这里我们为可选方法抛出NotImplementedException。此实现实现GetDataContractType以告诉调用者它支持CustomerOrderEvent并在序列化时使用CustomerOrderEventSurrrogate。它还实现GetObjectToSerializeGetDeserializeObject来代替来自代理人的POCO。

现在,您只需创建一个BrokeredMessage,其中DataContractSerializer实例知道您要使用的IDataContractSurrogate实现。例如:

var customerOrderEvent = new CustomerOrderEvent
                                {
                                    OrderId = 1,
                                    Quantity = 1,
                                    Value = 1.99
                                };

var dataContractSerializer =
    new DataContractSerializer(typeof (CustomerOrderEvent),
                                new[] {typeof (CustomerOrderEvent)},
                                int.MaxValue,
                                true,
                                true,
                                new DataContractSurrogate());

var message = new BrokeredMessage(customerOrderEvent, dataContractSerializer);

当您收到消息时,可以将DataContractSerializer对象传递给GetBody方法。例如:

message.GetBody<CustomerOrderEvent>(dataContractSerializer);

...假设对话的这一方做了与另一方相同的事情(有代理类,IDataContractSurrogate实现,并正确地创建了dataContractSerializer