Archive for the ‘Development’ Category

On the first part I described Value Injecter and how to use it in a object-to-object mapping. In this second part I’ll show a complete sample of how to map an object using the property names and converting the property types from the source to the target type.

using System;
using System.ComponentModel;
using Omu.ValueInjecter;

namespace Infrastructure.Mappers
{
    /// <summary>
    /// The custom loop value injector class will map all properties with the same name, even if the type is not the same.
    /// When the source and target types are not the same, a conversion will be attempted by a converter dynamically created.
    /// </summary>
    public class NameValueInjection : CustomizableValueInjection
    {
        #region Overrides of ValueInjection

        /// <summary>
        /// Injects the source object properties into the target object properties.
        /// </summary>
        /// <param name="source">The source object.</param>
        /// <param name="target">The target object.</param>
        protected override void Inject(object source, object target)
        {
            if (source == null || target == null)
                return;

            PropertyDescriptorCollection sourceProps = source.GetProps();
            PropertyDescriptorCollection targetProps = target.GetProps();

            //Get source properties length.
            int length = sourceProps.Count;

            //Loop over all source properties.
            for (int index = 0; index < length; index++)
            {
                //Get current source property.
                PropertyDescriptor sourceProp = sourceProps[index];
                //Get target property with the same name.
                PropertyDescriptor targetProp = targetProps.GetByName(SearchTargetName(sourceProp.Name));

                //Get value.
                object targetValue = GetTargetValue(source, sourceProp, targetProp);
                //Update value.
                SetTargetValue(target, targetProp, targetValue);
            }
        }

        /// <summary>
        /// Gets the target value.
        /// </summary>
        /// <param name="source">The source.</param>
        /// <param name="sourceProp">The source prop.</param>
        /// <param name="targetProp">The target prop.</param>
        /// <returns></returns>
        protected virtual object GetTargetValue(object source, PropertyDescriptor sourceProp, PropertyDescriptor targetProp)
        {
            //Validate target property.
            if (targetProp == null)
                return null;

            //Get the source property value.
            object sourceValue = sourceProp.GetValue(source);

            //Validate source value.
            if (sourceValue == null)
                return null;

            //Declare the target property value.
            object targetValue;

            //Check if the property types match.
            if (TypesMatch(sourceProp.PropertyType, targetProp.PropertyType))
            {
                //Get property value from the source object.
                targetValue = sourceValue;
            }
            else
            {
                try
                {
                    //Create a new type converter.
                    TypeConverter converter = TypeDescriptor.GetConverter(targetProp.PropertyType);
                    //Validate converter.
                    if (converter == null)
                        return null;

                    //Convert from the source to target type.
                    targetValue = converter.CanConvertFrom(sourceProp.PropertyType)
                                      ? converter.ConvertFrom(sourceValue)
                                      : Convert.ChangeType(sourceValue, targetProp.PropertyType);
                }
                catch
                {
                    //Log the exception here or rethrow.
                    return null;
                }
            }
            return targetValue;
        }

        /// <summary>
        /// Sets the target value.
        /// </summary>
        /// <param name="target">The target.</param>
        /// <param name="targetProp">The target prop.</param>
        /// <param name="value">The value.</param>
        protected virtual void SetTargetValue(object target, PropertyDescriptor targetProp, object value)
        {
            //If target value is valid set target value.
            if (value != null)
                targetProp.SetValue(target, value);
        }

        #endregion
    }
}

And that’s it, a conversion will be made to match the target type, and to use it you just need to write something like this:

target.InjectFrom<NameValueInjection>(source);

Happy coding.

I’m working on a project that requires a fair amount of object-to-object mapping, mostly due to the necessity to expose data to external systems using DTO’s (Data Transfer Objects).

As in many other cases the domain objects must be mapped to the DTO that will expose the data, and this is generally involves writing a lot of object-to-object mapping code, but fortunately there are several tools to help this task. After some searching I end up with two AutoMapper and Value Injecter.

Why using the two? Because both work in different ways, although the final result is to automatically map objects. AutoMapper seems to be more popular, so I’ll write about it in the future, for now I’ll talk a little bit about Value Injecter.
Value Injecter is a really small but powerful tool (I advice you to take a good look at the codeplex site). It’s also very easy to extend. It provides several classes to flattening and unflattening objects, and it very easy to use. It provides you with an extension method to inject the object, like this.

target.InjectFrom(source);

This will use the existing LoopValueInjection to inject the values from the source into the target object. All this is very nice and easy, the problem is that in the real world nothing is as simple as it seems. One of the conditions that object mappers evaluate is the name and type of each parameter. Lets take a look at an example similar to one of the documentation examples.

public class Person
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }
    public DateTime DateOfBirth { get; set; }
}

public class PersonViewModel
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Age { get; set; }
    public DateTime DateOfBirth { get; set; }
}

This is a simple but pretty common scenario. Properties that have the same name, but different types, and in reality they should be mapped to a different type. In my case, a common scenario is that integer values from the domain objects must be converted to strings in the DTO’s, and or vice versa. So in Value Inject you map these objects like this

personViewModel.InjectFrom(person) // this does the props of the same name and type
             .InjectFrom<IntToString>(person); // this does the props (by same name) that are of type int in viewmodel and of type string in person

And create a new value injector to map from int to string like this

public class IntToString : LoopValueInjection
{
    protected override bool TypesMatch(Type sourceType, Type targetType)
    {
        return sourceType == typeof(int) && targetType == typeof(string);
    }

    protected override object SetValue(object sourcePropertyValue)
    {
        return Convert.ToString(sourcePropertyValue);
    }
}

All this is great, but wouldn’t be better if you could create a generic injector. One that’s capable to convert the property using the appropriated conversion, knowing that the property name is the same. So let’s create a new injector that can do exactly that.

//Check if the property types match.
if (TypesMatch(sourceProp.PropertyType, targetProp.PropertyType))
{
    //Get property value from the source object.
    targetValue = sourceProp.GetValue(source);
}
else
{
    //Create a new type converter.
    TypeConverter converter = TypeDescriptor.GetConverter(targetProp.PropertyType);
    //Validate converter.
    if (converter == null)
        continue;

    //Convert from the source to target type.
    targetValue = converter.CanConvertFrom(sourceProp.PropertyType)
			? converter.ConvertTo(sourceValue, targetProp.PropertyType)
			: System.Convert.ChangeType(sourceValue, targetProp.PropertyType);
}

//Validate value
if (targetValue == null)
    continue;

//Set target value.
targetProp.SetValue(target, targetValue);

A TypeConverter is created based on the target type, and will try to convert using standard .net conversion methods. This will avoid the boring task to create different injectors for most framework types. More specific scenarios will always require custom injectors, but hopefully this will save some work.

The full source code can be downloaded from here.

The next step is to create an injector, that can convert properties of the same type but with  partial name matches. Like ReleaseDate to Release, or IsValid to Valid.

Hope this can help.

Some time ago I had the need to create an extensive amount of Xsd schemas from Xml instances. There are many tools or applications capable of generate an Xsd Schema from an Xml instance, it’s possible to use BizTalk, XmlSpy or Style Studio to name a few, but I needed something less “powerful”, I wanted a  simple tool with which I could open a file and simply generate the schema from it.
There was a website capable of create the schema using “XmlSchemaInference” class, but I thought, if the class is available with the .Net Framework why not create such a tool. And here it is Inference Tool.

main_screen

It’s really simple to use, just browse for a well formed Xml instance file, select “Infer” from the “Schema” menu, and a xsd schema is generated.

main_screen_generation

The project has a couple of years, but I hope it still can be useful.
It was converted to Visual Studio 2008 using the Express Edition, so if you don’t have a full copy of VS2008 you can download the Express Edition as well.

Inference Tool Binaries
Inference Tool Source (VS2008)

Any comments will be much appreciated.

I decided to install Drupal on my Vista x64 Machine, and what an adventure it was.

Installing a LAMP (Linux, Apache, MySql, PHP) Server is something I’ve done in the past, and I never had problems with it, I also installed PHP on Windows before, back in the “old” XP days.
I was curious to see how PHP was going to work with IIS 7, this was also an opportunity to explore some new feature available with IIS 7 namely the FastCGI support, Microsoft URL Rewrite Module for IIS 7.0 and the new administration console.

First things first, to install Drupal it’s required PHP and MySql. Installing MySql on Vista is easy enough, you just need to download the MSI file from MySql Site, run the setup and finally run the configuration utility (the setup does it automatically).
I’m using MySql with Vista an with Ubuntu as well, it works well on both systems. A lot of people are using myphpadmin to administer MySql Server, I personally prefer MySql Administrator. I prefer it because it’s fast and it’s not web based, the downturn it that I cannot administer the server remotely, but I don’t need that, so it works fine for me this was, you can dowloaded it from here.

That was the easy part. Install PHP was easy as well. But install FastCGI and configure PHP to use it was not so simple.
iis.net has a lot of very useful resources about IIS, PHP and FastCGI, unfortunately I discovered some of those only after this process.

Here are the ones I find most useful for this task:

Drupal on IIS
Partying with PHP on IIS 7
Using FastCGI to Host PHP Applications on IIS 7.0

I’ll not describe in detail what is required for each step, because all that information can be viewed using these links.

As I said unfortunately I discovered the first one after the installation. I read all of them and it was quite easy to find things and setup everything but as always there’s something that goes wrong.

The steps are the following:

  • Update IIS 7.0 FastCGI module
  • Enable FastCGI support in IIS
  • Install PHP (Here I prefer to run the MSI file but it’s also possible to unzip PHP to a folder and manually do the configurations, for me the main advantage of the MSI is that it should setup IIS for you, but that was not my case, also the installer will enabled all the extensions and that was one of my problems.)
  • Configure IIS to handle PHP Requests (This shouldn’t be necessary because the installer is designed to do this, I don’t know why but in my case this doesn’t worked, so I need to do the configuration.)
  • Install Drupal

If you read all the above tutorials you should be fine.

The first thing I read was “Using FastCGI to Host PHP Applications on IIS 7.0″”, but I made some mistakes.
First I installed PHP with CGI support and not FastCGI, it all seems to work great, and I could see the famous phpinfo() returning the standard information, but as soon I try to install Drupal I got a lot of errors.
It seemed that PHP was unable to find all the extensions, I checked php.ini and the extension folder was pointing to the correct location.
I checked the permissions for ISURS and Network Service and they where correct, so instead of trying to fix this I wanted to enabled FastCGI. And so I did, I deleted the Handler Mapping on IIS and created the correct mapping using FastCGI, then I tried phpinfo to see if everything was ok and immediately IIS crashed. Locking further what I discovered was that some extension that came with PHP was causing errors, what I did was to disable all the extensions, as soon I did it phpinfo() was again OK, so I went to Drupal setup and enabled only the extensions required for the setup, that are basically mysql and mbstring to enable Unicode support.
Another thing that happened during setup was that the process was unable to configure the database connection, so I needed to manually edit the file and change it. This is quite a simple process just edit “setting.php” file from “/sites/default”, locate the “$db_url” and changed the values.
I still didn’t understand completely what was wrong when activating FastCGI support for the first time, but probably the best thing to do is to disable all the extension before enabling FastCGI. That way it’s easier to isolate the problems.
There’s also the security questions, that last time I setup PHP on Windows was with Windows XP, Vista is far more sensible to permission issues that XP, so it’s best to understand which users and folders you need to give access to before installing.

Again this is an easier process with Linux, but all in all it was an interesting challenge to do it on Vista, I’m glad that in the end all worked well.

In my previous serialization post, I wrote a class to serialize and deserialize to and from xml.
Well that class suffers from a couple of issues, to start it’s not thread safe, and also doesn’t make use of generics.
So I revisited the code, and introduced what I hope to be an improvement from previous version.

Here it is.

The Serialize method returns an xml string from a given object.

        /// <summary>
        /// Serializes the specified object to an xml string using the specified encoding.
        /// </summary>
        /// <typeparam name="T">The generic object type.</typeparam>
        /// <param name="source">The source.</param>
        /// <param name="encoding">The encoding to encode the returned xml string.</param>
        /// <returns>An Xml String with the object content.</returns>

        public static string Serialize<T>(T source, Encoding encoding)
        {
            // The string to hold the object content
            String content;

            // Create a memoryStream into which the data can be written and readed
            using (MemoryStream stream = new MemoryStream())
            {
                // Create the xml serializer, the serializer needs to know the type 
                // of the object that will be serialized
                XmlSerializer xmlSerializer = new XmlSerializer(source.GetType());

                // Create a XmlTextWriter to write the xml object source, we are going 
                // to define the encoding in the constructor
                using (XmlTextWriter writer = new XmlTextWriter(stream, encoding))
                {
                    // Save the state of the object into the stream
                    xmlSerializer.Serialize(writer, source);
                    // Flush the stream
                    writer.Flush();
                    // Read the stream into a string
                    using (StreamReader reader = new StreamReader(stream, encoding))
                    {
                        // Set the stream position to the begin
                        stream.Seek(0, SeekOrigin.Begin);
                        // Read the stream into a string
                        content = reader.ReadToEnd();
                    }
                }
            }

            // Return the xml string with the object content
            return content;
        }

 

The Deserialize method does the oposite, returns an object from an xml string.

        /// <summary>
        /// Deserializes the specified xml string to an object of type T using the specified encoding.
        /// </summary>
        /// <typeparam name="T">The new object.</typeparam>
        /// <param name="content">The xml string content.</param>
        /// <param name="encoding">The string encoding.</param>
        /// <returns>A new object of type T.</returns>

        public static T Deserialize<T>(string content, Encoding encoding)
        {
            // The object to be returned
            T source;

            // Create a memorystream into which the object string will be written
            using (MemoryStream stream = new MemoryStream())
            {
                // Create the sream writer with the specified encoding
                using (StreamWriter writer = new StreamWriter(stream, encoding))
                {
                    // Write the object content into the stream
                    writer.Write(content);

                    // Flush the stream
                    writer.Flush();

                    // Create the serializer, we must provide the object type to the constructor
                    Type type = typeof(T);
                    XmlSerializer xmlSerializer = new XmlSerializer(type);

                    // Set the stream position to the begin
                    stream.Seek(0, SeekOrigin.Begin);
                    // Deserialize the object
                    source = (T)xmlSerializer.Deserialize(stream);
                }
            }

            // Return the new object
            return source;
        }

 

Each method accept the string encoding as parameter, there is one overload for each method that uses UTF8 as the default encoding.

You can download the class from here.

For a quick translation click here.

A serialização de objectos é por definição uma técnica usada para persistir objectos, pode ser utilizada para gravar objectos em disco, fazer a transmissão remota de objectos, ou gravar os objectos em base de dados.

Podemos apontar mais utilizações como por exemplo:

  • Guardar as preferências de um utilizador num objecto
  • Passar objectos entre aplicações
  • Modificar ou transformar o conteúdo de um objecto

É uma funcionalidade muito poderosa, e o destino a dar á sua utilização depende em ultima análise da imaginação e das necessidades de cada um, as possibilidades são variadas.

Em .Net existem dois formatos em que um objecto pode ser serializado, o formato binário ou o formato xml. Vamos ver como podemos usar a serialização neste ultimo caso, uma vez que um ficheiro xml permite uma fácil leitura e manipulação do seu conteúdo, sendo neste momento possivelmente o formato mais usado para a troca de dados.

Para um objecto ser serializado em Xml tem de cumprir os seguintes requisitos:

  • Tem de ter um default constructor, ou seja um construtor sem parâmetros
  • Todas as propriedades a serem serializadas tem de ser Read\Write, as propriedades Real Only não são serializáveis

E tem também algumas regras:

  • Apenas as propriedades e membros públicos são serializáveis
  • A serialização não inclui informação sobre o tipo, ou seja para Serializar e Deserializar é necessário indicar qual o tipo do objecto

As classes e atributos necessário para a serialização estão no namespace System.Xml.Serialization, vamos para este exemplo explorar a classe XmlSerializer e alguns atributos úteis para a serialização.

XmlSerializer:

Esta é a classe principal deste namespace, e tal como está descrito na documentação permite converter as propriedades e membros públicos para um formato que lhes permita serem guardados ou transportados. E também recriar um objecto a partir desse formato, no nosso caso esse formato é Xml.

Os principais métodos desta classe são:
Serialize: Permite guardar o objecto para um stream
Deserialize: Permite recriar o objecto a partir de um stream

Este stream pode ser manipulado de várias formas, pode ser gravado para um ficheiro xml, e deste modo vamos usar a serialização para persistir o objecto, ou então o seu valor pode ser escrito numa string, neste caso pode ou não persistir, dependendo da utilização que for dada a essa string, pode ainda servir por exemplo para transferir um objecto utilizando para tal um stream http.

Atributos:

Além da classe XmlSerializer, existem várias classes de atributos, atributos esses que podem ser usados para definir com um objecto vai ser serializado, estão descritos na documentação pelo que vamos ver apenas alguns exemplos para ilustrar a sua utilização

[XmlRoot("Order", Namespace = "http://www.sampleOne.com/sales")]

O atributo XmlRoot é usado ao nível da classe e permite definir por exemplo qual o nome do root element do Xml, e qual o seu namespace

[XmlAttribute("customerId")]

Por defeito os elementos da classe a serializar são escritos no xml na forma de nós o que o atributo XmlAttribute permite é indicar que determinado elemento vai ser guardado como atributo de um nó

[XmlIgnore]

Tal como indica o nome este atributo permite identificar que determinada propriedade ou membro não irá ser serializado.

Vamos ver agora um pequeno exemplo, para este exemplo vamos usar as seguintes classes:


As classes SalesOrder e SalesOrderItem, representam tal como os nomes indicam uma encomenda e os respectivos items.
Em ambas as classes todos os membros são privados, estando encapsulados por propriedades publicas, sendo assim apenas estas propriedades serão serializadas.

Para fazer a serialização e deserialização vamos usar a seguinte classe:

O método Serialize retorna uma string xml com o conteúdo de um dado objecto, o método Deserialize faz o inverso, ou seja, a partir de uma string xml com o conteúdo de um objecto e do seu tipo, cria uma nova instancia desse objecto. Além disso permite a escolha de qual o encoding a utilizar nestes métodos.

Estão aqui em detalhe cada um dos métodos, espero que os comentários sejam suficientemente elucidativos:

    public static class MemorySerializer
    {
        #region Private Static Members
        // The default encoding to use in the serialization process
        private static Encoding encoding = Encoding.UTF8;
        #endregion
        #region Public Methods
        /// <summary>
        /// Serializes the specified source.
        /// </summary>
        /// <param name="source">The source.</param>
        /// <returns></returns>
        public static string Serialize(object source)
        {
            // The string to hold the object content
            String content;
            // Create a memoryStream into which the data can be written and readed
            using (MemoryStream stream = new MemoryStream())
            {
                // Create the xml serializer, the serializer needs to know the type 
                // of the object that will be serialized
                XmlSerializer xmlSerializer = new XmlSerializer(source.GetType());
                // Create a XmlTextWriter to write the xml object source, we are going 
                // to define the encoding in the constructor
                using (XmlTextWriter writer = new XmlTextWriter(stream, Encoding))
                {
                    // Save the state of the object into the stream
                    xmlSerializer.Serialize(writer, source);
                    // Flush the stream
                    writer.Flush();
                    // Read the stream into a string
                    using (StreamReader reader = new StreamReader(stream, Encoding))
                    {
                        // Set the stream position to the begin
                        stream.Position = 0;
                        // Read the stream into a string
                        content = reader.ReadToEnd();
                    }
                }
            }
            // Return the xml string with the object content
            return content;
        }
        /// <summary>
        /// Deserializes the specified object string.
        /// </summary>
        /// <param name="content">The object string.</param>
        /// <param name="type">Type of the object.</param>
        /// <returns></returns>
        public static object Deserialize(string content, Type type)
        {
            // The object to be returned
            object source;
            // Create a memorystream into which the object string will be written
            using (MemoryStream stream = new MemoryStream())
            {
                // Create the sream writer with the specified encoding
                using (StreamWriter writer = new StreamWriter(stream, Encoding))
                {
                    // Write the object content into the stream
                    writer.Write(content);
                    // Flush the stream
                    writer.Flush();
                    // Create the serializer, we must provide the object type to the constructor
                    XmlSerializer xmlSerializer = new XmlSerializer(type);
                    // Set the stream position to the begin
                    stream.Position = 0;
                    // Deserialize the object
                    source = xmlSerializer.Deserialize(stream);
                }
            }
            // Return the new object
            return source;
        }
        #endregion
        #region Public Properties
        /// <summary>
        /// Gets or sets the encoding.
        /// </summary>
        /// <value>The encoding.</value>
        public static Encoding Encoding
        {
            get { return encoding; }
            set { encoding = value; }
        }
        #endregion
    }

O exemplo de utilização consiste no seguinte:

Uma pequena Windows Application, que permite a edição do conteúdo dos objecto num layout gráfico e também a sua edição em Xml, deste modo podemos editar directamente o xml e verificar como o objecto criado reflecte essas mesmas alterações.

Este é um pequeno exemplo de uma das múltiplas utilizações da serialização, e de como pode ser usada para visualizar e editar o conteúdo de um objecto.

Links:
Sample Application