jueves, 31 de mayo de 2012

miércoles, 23 de mayo de 2012

Mejorando como programador

Leyendo cosas de Carlos Ble, ha escrito sobre un sitio, para mejorar como programador.

String.Empty vs ""

Estudiando LessFramework, me he encontrado que para incializar las cadenas de texto, hace uso de String.Empty.
string callingMethod = String.Empty;
Me ha entrado la curiosidad y he estado googleando, para ver la razón que hay detrás, me he encontrado una página, que dice que es más eficiente String.Emtpy, porque no crea un objeto (es un mñetodo estático) y por lo tanto se ahorra memoria, pero en cambio con "", se crea un objeto y tiene que ponerlo en la pila de los objetos, por lo tanto afecta algo (muy muy poco) al rendimiento.

martes, 22 de mayo de 2012

Unix desde AT&T

Me he encontrado un video que cuenta la historia de Unix y la página es de la propia AT&T

El código que me encuentro en el trabajo

Me pregunto si realmente somo buenos programadores o nos merecenos lo que tenemos.
Porque viendo este código ya me entran las dudas. Eso sí, sigo con ganas de seguir mejorando como programador, porque si no tuviera estas ganas de aprender, seguro que generaría este código o aún peor. Un compañero de profesión me dijo una vez que él escribía el código todo seguido ...

       private void AplicarContorno(Control control, bool aplicar)
        {
            var canvas = (Canvas)control.FindName("Canvas");
            foreach (var poligono in canvas.Children)
            {
                try
                {
                    var path = (Path)poligono;
                    if (aplicar)
                    {
                        path.Stroke = Brushes.Black;
                    }
                    else
                    {
                        path.Stroke = Brushes.Transparent;
                    }
                }
                catch (Exception)
                {
                    try
                    {
                        var canvas2 = (Canvas)poligono;
                        if (canvas2 != null)
                        {
                            foreach (var municipio in canvas2.Children)
                            {
                                var path2 = (Path)municipio;
                                if (aplicar)
                                    path2.Stroke = Brushes.Black;
                                else
                                    path2.Stroke = Brushes.Transparent;
                            }
                        }
                    }
                    catch
                    {
                    }
                }
            }
        }

jueves, 17 de mayo de 2012

ASP.NET MVC

Cuando se comienza a conocer una tecnología, uno está muy perdido, por lo menos es lo que me pasa ahora que me ha dado por estudiar MVC y mi olfato me dice que las cosas van a ir por aquí. Mirando cosas sobre este tema, me he encontrado un video, que da una buena visión (esa es mi sensación), para montar un proyecto con testa tecnología.
Espero que sea utilidad.
Me he dado cuenta de que hay más videos.

Una forma distinta de ver las horas

Enlace

Fichero de Log Asíncrono

Hablando con algunos compañeros de trabajo, estábamos debatiendo sobre emplear ficheros de log. Soy firme defensor de ello, porque ante un error en producción, hay que conocer el porqué del fallo. El problema que nos encontrábamos era que al hacer uso de ficheros de log, la fvelocidad, disminuía muchísmo. así que buscando un poco he pensado que una buena solución es generar los ficheros de log de forma asíncrona. Se emplean las EnterPriseLibrary, porque para qué reinventar la rueda, por lo tanto no hay que olvidar la .dll.

using Microsoft.Practices.EnterpriseLibrary.Logging;

namespace ClassLibrary1
{
    public class Log
    {
        delegate void WriteLogDelegate(string message);

        public static void WriteLog(string message)
        {
            WriteLogDelegate logDelegate = new WriteLogDelegate(AsyncWriteLog);
            AsyncHelper.FireAndForget(logDelegate, message);
        }

        static void AsyncWriteLog(string message)
        {
            LogEntry log = new LogEntry();
            log.Message = message;

            Logger.Write(log);
        }      
      
    }
}
using System;

namespace ClassLibrary1
{
    /// <summary>
    /// This is asynchronous helper class from Jon Skeet
    /// http://www.yoda.arachsys.com/csharp/threads/threadpool.shtml
    /// </summary>
    public class AsyncHelper
    {
        /// <summary>
        /// Delegate to wrap another delegate and its arguments
        /// </summary>
        delegate void DelegateWrapper(Delegate d, object[] args);

        /// <summary>
        /// An instance of DelegateWrapper which calls InvokeWrappedDelegate,
        /// which in turn calls the DynamicInvoke method of the wrapped
        /// delegate.
        /// </summary>
        static DelegateWrapper wrapperInstance = new DelegateWrapper(InvokeWrappedDelegate);

        /// <summary>
        /// Callback used to call <code>EndInvoke</code> on the asynchronously
        /// invoked DelegateWrapper.
        /// </summary>
        static AsyncCallback callback = new AsyncCallback(EndWrapperInvoke);

        /// <summary>
        /// Executes the specified delegate with the specified arguments
        /// asynchronously on a thread pool thread.
        /// </summary>
        public static void FireAndForget(Delegate d, params object[] args)
        {
            // Invoke the wrapper asynchronously, which will then
            // execute the wrapped delegate synchronously (in the
            // thread pool thread)
            wrapperInstance.BeginInvoke(d, args, callback, null);
        }

        /// <summary>
        /// Invokes the wrapped delegate synchronously
        /// </summary>
        static void InvokeWrappedDelegate(Delegate d, object[] args)
        {
            d.DynamicInvoke(args);
        }

        /// <summary>
        /// Calls EndInvoke on the wrapper and Close on the resulting WaitHandle
        /// to prevent resource leaks.
        /// </summary>
        static void EndWrapperInvoke(IAsyncResult ar)
        {
            try
            {
                wrapperInstance.EndInvoke(ar);
                ar.AsyncWaitHandle.Close();
            }
            catch (Exception ex)
            {
                //Handle the exception.
            }
        }
    }
}


También hay que crear un fichero de configuración, que en este caso se llama: App.config y el contenido es:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
  </configSections>
  <loggingConfiguration name="Logging Application Block" tracingEnabled="true"
    defaultCategory="General" logWarningsWhenNoCategoriesMatch="true">
    <listeners>
      <add fileName="SVPBuildTool.log" rollSizeKB="0" timeStampPattern="yyyy-MM-dd"
        rollFileExistsBehavior="Increment" rollInterval="Day" formatter="Text Formatter"
        header="----------------------------------------" footer="----------------------------------------"
        listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.RollingFlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
        traceOutputOptions="None" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.RollingFlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
        name="Rolling Flat File Trace Listener" />
    </listeners>
    <formatters>
      <add template="Timestamp: {timestamp}&#xD;&#xA;Message: {message}&#xD;&#xA;Category: {category}&#xD;&#xA;Priority: {priority}&#xD;&#xA;EventId: {eventid}&#xD;&#xA;Severity: {severity}&#xD;&#xA;Title:{title}&#xD;&#xA;Machine: {machine}&#xD;&#xA;Application Domain: {appDomain}&#xD;&#xA;Process Id: {processId}&#xD;&#xA;Process Name: {processName}&#xD;&#xA;Win32 Thread Id: {win32ThreadId}&#xD;&#xA;Thread Name: {threadName}&#xD;&#xA;Extended Properties: {dictionary({key} - {value}&#xD;&#xA;)}"
        type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
        name="Text Formatter" />
    </formatters>
    <categorySources>
      <add switchValue="All" name="General">
        <listeners>
          <add name="Rolling Flat File Trace Listener" />
        </listeners>
      </add>
    </categorySources>
    <specialSources>
      <allEvents switchValue="All" name="All Events">
        <listeners>
          <add name="Rolling Flat File Trace Listener" />
        </listeners>
      </allEvents>
      <notProcessed switchValue="All" name="Unprocessed Category" />
      <errors switchValue="All" name="Logging Errors &amp; Warnings" />
    </specialSources>
  </loggingConfiguration>
</configuration>

miércoles, 16 de mayo de 2012

Ejercicios para mejorar como programador

Code Chef es una página en la que se proponen ejercicios para que el programador mejore su forma de hacer las cosas.

viernes, 11 de mayo de 2012

Impress.js

Leyendo cosas de Fernando Blat (hace algunos años que le voy siguiendo la pista), me he encontrado con la librería para hacer presentaciones en la web. Cada vez estoy más impresionado.

He probado la página de demo y me he encontrado una grata sorpresa al ver su código fuente. Tengo que reconocer que soy de los que mira el código fuente de las páginas, para darme cuenta de todo lo que me queda.

Con unas cuantas cosas, se pueden hacer maravillas. La recomiendo muy fervientemente.

miércoles, 9 de mayo de 2012

Marshalling

 public static int? ToNullInt(string t)
    {
        int i = 0;
        if (int.TryParse(t, out i))
        {
            return i;
        }
        else
        {
            return null;
        }
    }
    public static short? ToNullShort(string t)
    {
        short i = 0;
        if (short.TryParse(t, out i))
        {
            return i;
        }
        else
        {
            return null;
        }
    }
    public static DateTime? ToNullDate(string t)
    {
        DateTime d = new DateTime();
        if (DateTime.TryParse(t, out d))
        {
            return d;
        }
        else
        {
            return null;
        }
    }
    public static decimal? ToNullDecimal(string t)
    {
        decimal d = 0;
        if (decimal.TryParse(t, out d))
        {
            return d;
        }
        else
        {
            return null;
        }
    }
    public static byte? ToNullByte(string t)
    {
        byte d = 0;
        if (byte.TryParse(t, out d))
        {
            return d;
        }
        else
        {
            return null;
        }
    }
    public static bool? ToNullBool(string t)
    {
        bool d = false;
        if (bool.TryParse(t, out d))
        {
            return d;
        }
        else
        {
            return null;
        }
    }
    public static string ToNullString(string t)
    {
        if (!string.IsNullOrEmpty(t))
        {
            return t;
        }
        else
        {
            return null;
        }
    }
    public static object ToNullValue(PropertyInfo propiedadDestino, PropertyInfo propiedadOrigen, Object objeto)
    {
        if (propiedadDestino.PropertyType == typeof(DateTime)
        || propiedadDestino.PropertyType == typeof(DateTime?))
        {
            return ToNullDate(propiedadOrigen.GetValue(objeto, null).ToString());
        }
        else if (propiedadDestino.PropertyType == typeof(int)
        || propiedadDestino.PropertyType == typeof(int?))
        {
            return ToNullInt(propiedadOrigen.GetValue(objeto, null).ToString());
        }
        else if (propiedadDestino.PropertyType == typeof(Int16)
        || propiedadDestino.PropertyType == typeof(Int16?))
        {
            return ToNullShort(propiedadOrigen.GetValue(objeto, null).ToString());
        }
        else if (propiedadDestino.PropertyType == typeof(decimal)
        || propiedadDestino.PropertyType == typeof(decimal?))
        {
            return ToNullDecimal(propiedadOrigen.GetValue(objeto, null).ToString());
        }
        else if (propiedadDestino.PropertyType == typeof(byte)
        || propiedadDestino.PropertyType == typeof(byte?))
        {
            return ToNullByte(propiedadOrigen.GetValue(objeto, null).ToString());
        }
        else if (propiedadDestino.PropertyType == typeof(bool)
        || propiedadDestino.PropertyType == typeof(bool?))
        {
            return ToNullBool(propiedadOrigen.GetValue(objeto, null).ToString());
        }
        else if (propiedadDestino.PropertyType == typeof(string))
        {
            object value = propiedadOrigen.GetValue(objeto, null);
            if (((string)value) == "") value = null;
            return value;
        }
        else
        {
            return propiedadOrigen.GetValue(objeto, null);
        }
    }
    public static Control GetControl(string id, Control contenedor)
    {
        Control control = contenedor.FindControl(id);
        if (control != null) return control;
        if (contenedor.Controls.Count != 0)
        {
            foreach (Control c in contenedor.Controls)
            {
                control = GetControl(id, c);
                if (control != null) return control;
            }
        }
        return null;
    }
    public static object FillObject(Control controlPadre, Type type, string prefijoIdControl)
    {
        //Crea un objeto del tipo dado
        object entity = Activator.CreateInstance(type);

        // Para cada propiedad del objeto
        foreach (PropertyInfo propiedad in type.GetProperties())
        {
            if (propiedad.CanWrite)
            {
                //Busca un control con id igual a "rep_" mas el nombre de la propiedad
                string idControl = string.Format("{0}{1}", prefijoIdControl, propiedad.Name);
                Control control = GetControl(idControl, controlPadre);

                //Si el control existe
                if (control != null)
                {
                    // Segun el tipo del control necesitamos una propiedad concreta
                    string nombrePropieda = "";
                    if (control is Ext.Net.CheckColumn) nombrePropieda = "Checked";
                    else if (control is Ext.Net.Hidden) nombrePropieda = "Value";
                    else if (control is Ext.Net.ComboBox) nombrePropieda = "SelectedValue";
                    else nombrePropieda = "Text";

                    // Recuperamos la propiedad del control que vamos a leer
                    PropertyInfo propiedadControl = control.GetType().GetProperty(nombrePropieda);

                    // Si la propiedad esta disponible
                    if (propiedadControl != null && propiedadControl.CanRead)
                    {
                        propiedad.SetValue(entity, ToNullValue(propiedad, propiedadControl, control), null);
                    }
                }
            }
        }
        return entity;
    }
    public static bool IsNullObject(object obj)
    {
        object propiedadControl;
        bool resultado = true;

        // Para cada propiedad del objeto
        foreach (PropertyInfo propiedad in obj.GetType().GetProperties())
        {
            if ((null != propiedad) && (propiedad.CanRead))
            {
                // Recuperamos la propiedad del control que vamos a leer
                propiedadControl = propiedad.GetValue(obj, null);
                if ((null != propiedadControl) &&
                    (false == propiedadControl.ToString().Contains("List"))) //No se toma en cuenta las listas --> IList
                {
                    resultado = false;
                    break;
                }

            }
        }
        return resultado;
    }
    public static void FillControl<t>(Control controlPadre, t entity)
    {
        FillControl(controlPadre, entity, "");
    }
    public static void FillControl<t>(Control controlPadre, t entity, string prefijoIdControl)
    {

        // Para cada propiedad del objeto
        foreach (PropertyInfo propiedad in entity.GetType().GetProperties())
        {
            if (propiedad.CanRead)
            {
                //Busca un control con id igual a "rep_" mas el nombre de la propiedad
                string idControl = string.Format("{0}{1}", prefijoIdControl, propiedad.Name);
                Control control = GetControl(idControl, controlPadre);

                //Si el control existe
                if (control != null)
                {
                    // Segun el tipo del control necesitamos una propiedad concreta
                    string nombrePropieda = "";
                    if (control is CheckColumn) nombrePropieda = "Checked";
                    else if (control is Hidden) nombrePropieda = "Value";
                    else if (control is ComboBox) nombrePropieda = "SelectedValue";
                    else if (control is Image) nombrePropieda = "ImageUrl";
                    else nombrePropieda = "Text";

                    // Recuperamos la propiedad del control que vamos a leer
                    PropertyInfo propiedadControl = control.GetType().GetProperty(nombrePropieda);

                    // Si la propiedad esta disponible
                    if (propiedadControl != null)
                    {
                        object value = propiedad.GetValue(entity, null);
                        //porque el setvalue, da problemas con el tipo boolean
                        if ((value != null) && (value.GetType() != typeof(Boolean)))
                            propiedadControl.SetValue(control, value.ToString(), null);
                        else
                            propiedadControl.SetValue(control, value, null);
                    }
                }
            }
        }
    }
    public static void ClearControl<t>(Control controlPadre, t entity, string prefijoIdControl)
    {
        // Para cada propiedad del objeto
        foreach (PropertyInfo propiedad in entity.GetType().GetProperties())
        {
            if (propiedad.CanRead)
            {
                //Busca un control con id igual a "rep_" mas el nombre de la propiedad
                string idControl = string.Format("{0}{1}", prefijoIdControl, propiedad.Name);
                Control control = GetControl(idControl, controlPadre);

                //Si el control existe
                if (control != null)
                {
                    // Segun el tipo del control necesitamos una propiedad concreta
                    string nombrePropieda = "";
                    if (control is CheckColumn) nombrePropieda = "Checked";
                    else if (control is Hidden) nombrePropieda = "Value";
                    else if (control is ComboBox) nombrePropieda = "SelectedValue";
                    else if (control is Image) nombrePropieda = "ImageUrl";
                    else nombrePropieda = "Text";

                    // Recuperamos la propiedad del control que vamos a leer
                    PropertyInfo propiedadControl = control.GetType().GetProperty(nombrePropieda);

                    // Si la propiedad esta disponible
                    if (propiedadControl != null)
                    {
                        propiedadControl.SetValue(control, null, null);
                    }
                }
            }
        }
    }

Videos sobre TDD

Navegando (que raro), me he encontrado esta serie de videos sobre TDD

Trabajos

Los mejores 25 trabajos.