开发者

Strategies for serializing an object for auditing/logging purpose in .NET?

开发者 https://www.devze.com 2023-01-03 09:00 出处:网络
Let\'s say I have an application that processes messages.Messages are just objects in this case that implements IMessage interface which is just a marker.

Let's say I have an application that processes messages. Messages are just objects in this case that implements IMessage interface which is just a marker.

In this app, if a message fails to process, then I want to log it, first of all for auditing and troubleshooting purposes. Secondly I might want to use it for re-processing.

Ideally, I want the message to be serialized into a format that is human-readable. The first candidate is XML although there are others like JSON. If I were to serialize the messages as XML, I want to know whether the message object is XML-serializable. One way is to reflect on the type and to see if it has a parameter-less constructor and the other is to require IXmlSerializable interface. I'm not too happy with either of these approaches. There is a third option which is to try to serialize it and catch exceptions开发者_如何学Go. This doesn't really help - I want to, in some way, stipulate that IMessage (or a derived type) should be xml-serializable.

The reflection route has obvious disadvantages such as security, performance, etc. IXmlSerializable route locks down my messages to one format, when in the future, I might want to change the serialization format to be JSON. The other thing is even the simplest objects now must implement ReadXml and WriteXml methods.

Is there a route that involves the least amount of work that lets me serialize an arbitrary object (as long as it implements the marker interface) into XML but not lock future messages into XML?


You could implement a MessageBase that all your message objects derive from that contains a parameterless constructor. Then use MessageBase rather than IMessage.

Curious though, if you design the messages and have the intention for them to all be serializable why do you need to check?

Here's a generic object extension I use a lot:

/// <summary>        
/// Converts an object to a serialized xml string       
/// </summary>
/// <param name="o">The <see cref="object"/> to serialize</param>
/// <returns></returns>
public static string ToXml(this object o)
{
    XmlSerializer xmlSerializer = new XmlSerializer(o.GetType());

    using (MemoryStream memoryStream = new MemoryStream())
    {
        using (StreamWriter streamWriter = new StreamWriter(memoryStream))
        {
            xmlSerializer.Serialize(streamWriter, o);
            streamWriter.Flush();
            memoryStream.Flush();
            memoryStream.Position = 0;

            using (StreamReader streamReader = new StreamReader(memoryStream))
            {
                return streamReader.ReadToEnd();
            }
        }
    }
}

Implement it on your MessageBase and you're golden. No locking in to anything.


So the requirement is to serialize an arbitrary object (as long as it implements the marker interface) into human readable format (possibly XML) in the easiest possible manner.

As mentioned in Is It Serializable? determining if an object is serializable is hard.

I can think of only 2 ways to meet the requirements:

  1. Add a Serialize method to the IMessage interface and force classes to implement their own human readable format.
  2. Have your application interface be exposed as a service that accepts a human readable format. e.g. a WCF service that accepts a human readable message (XML) that you can log.

Option 1 may be good for auditing but not so much for reprocessing. Also there are still some edge cases that might cause problems.

If this is an existing application then those are probably not viable options. If that is the case then maybe look at something like Json.NET to try to serialize on a best effort basis.

0

精彩评论

暂无评论...
验证码 换一张
取 消