Domanda

I have been trying to make my application as configurable as possible.

I am using the Unity container and trying to use interfaces for everything.

At some point in my application I need to serialize my DTOs to XML and then do something with that XML using a DataAccess layer.

However, I had a thought in mind. Why should it always be XML? Shouldn't that also be something that can be configured in the container? The Serialization type or something like that?

I understand there is the XmlAttributes that can be used but that is tightly coupling the serialization to Xml. I was thinking of using ISerializable but I noticed that IXmlSerializable does not implement ISerializable.

So does anyone know how I could use an interface / base / abstract class to allow for configurable serialization which can be configured through the DI container?

È stato utile?

Soluzione

Theoretically I think outputformat-agnostic attributes could be possible, although it depends on how (dis)similar the output formats are that you want to support. For example, XML and JSON both use field names but JSON doesn't have the distinction between attributes and elements that XML has. Binary serialization on the other hand usually has no use for field names because the information is usually stored positional.

To be honest though, I've never seen such an implementation.

What I have seen happen frequently is that you define two "schemas":

  • One with all the entity classes defined in a storage-agnostic way and designed to be easy to handle in your business logic (i.e. with calculated properties, inheritance, and whatever else might help you).
  • And another set of classes designed solely to be serialized to one specific output format. For XML this could mean using [XmlAttribute]s, for storage in a database this could be using [PrimaryKey] attributes, but also having the data of one logical entity spread over multiple entities because a database stores its data more normalized.

Serializing the storage-agnostic entities then comes down to first mapping them to the storage-specific types, and then serializing these types. The mapping code can be written by hand, or be done by something as AutoMapper.

The key here is that rather than using 1 set of attributes that try to cover all your serialization needs, it is generally more feasible to create a complete new set of entities that are designed specifically to be serialized to one format.


As an aside, If I may give some unsolicited advice: I have yet to see an application that needed the serialization format to be pluggable. I mean, I understand the need for separation of concerns, and that "the rest of the application shouldn't be bothered by knowing this-or-that", but at some point you have to make some decisions about such things as in what database your data will be stored, or what kind of webservice API your application will provide.
Deferring these decisions or trying too hard to abstract them away will usually hurt how understandable your code looks and how easy it will be to add new features to it.

There is a fine line between "separation of concerns" on one side, and "making it possible to swap one database engine for another" on the other side. It is true that when you have separation of concerns it is generally easier to change the type of database that you're using, but (in my opinion) being able to swap database types should be a consequence, not a goal on its own.

To take the point back to your question: I don't think its bad if it takes more effort than reconfiguring your DI container to change the way it serializes its entities - changing this almost never happens in reality anyway.
As long as you keep the knowledge about the serialization confined to a specific part of your application, so that you don't have to plough through all your code when you do have to change it :)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top