1

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

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

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

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

在接收期间,我会:

  1. 检索消息并返回对象类型
  2. 查找我的地图,调用已注册此事件消息的事件

虽然描述起来很简单,但第一步就是把我的头发拉出来。

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

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

4

1 回答 1

3

在某些时候,您必须有一个带有 , 等属性的类DataContract才能DataMember发送到DataContactSerializer. 但是,您不必将它们添加到您的 POCO。

一种选择是简单地创建一个 DTO,使用与 POCO 相同的数据填充该 DTO。这个 DTO 你会用BrokeredMessage. 或者,您可以简单地将您的 POCO 以某种方式序列化为 aStream并将其提供给 aBrokeredMessage

另一种方法是使用 .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告诉调用者它支持CustomerOrderEventCustomerOrderEventSurrrogate在序列化时使用。它还实现GetObjectToSerializeGetDeserializeObject从代理到 POCO 的来回映射。

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

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正确创建。)

于 2013-03-16T17:21:10.150 回答