Generando un ensamblado dinamicamente y verificandolo

En estas semanas estuve trabajando en una caracteristica dentro de nuestro framework, que involucra crear un ensamblado dinamicamente y verificarlo. Esto pronto será reemplazado por Roslyn, pero mientras continuo trabajando en ello, aquí me permito compartir con ustedes el código mas importante:

 

El código que genera la DLL

private
static
CompilerErrorCollection _errs = null;

private
static
List<string> errors = new
List<string>();

 

public
static
bool GenerateDLL(string path)

{


var yourCodeAsString = @»using System; using System.Collections.Generic; namespace MainProcess

{

class Program

{

private static Random rdx = new Random();

static void Main(string[] args)

{

for (int i = 0; i < rdx.Next(1,21); i++)

{

Console.WriteLine(rdx.Next(100, 1001));

}

}

}

;


CSharpCodeProvider codeProvider = new
CSharpCodeProvider();


ICodeCompiler icc = codeProvider.CreateCompiler();

System.CodeDom.Compiler.CompilerParameters parameters = new
CompilerParameters();

parameters.GenerateExecutable = false;

parameters.OutputAssembly = path + @»AutoGen.dll»;


CompilerResults results = icc.CompileAssemblyFromSource(parameters, yourCodeAsString);

 


if (results.Errors.Count > 0)

{

_errs = results.Errors;

 


foreach (CompilerError error in results.Errors)

{


if (error.IsWarning) continue;

errors.Add(string.Format(«{0} at line {1} column {2}«,

error.ErrorText, error.Line, error.Column));

}

 


return
false;

}


return
true;

}

 

Finalmente el código que verifica la DLL:

GenerateDLL(path);

 


var pi = new
ProcessStartInfo(«PeVerify.exe», path + @»AutoGen.dll /md /il /nologo»)

{

UseShellExecute = false,

RedirectStandardOutput = true,

WorkingDirectory = Environment.CurrentDirectory,

CreateNoWindow = true,

};

 


using (var p = Process.Start(pi))

{


string stdOut = p.StandardOutput.ReadToEnd();

p.WaitForExit();


if (p.ExitCode != 0)

{


Console.WriteLine(stdOut);

 

}

}

 


Console.WriteLine(«Finished!»);

 

Saludos

Como saber si estoy conectado a Internet desde Windows Phone

Un requisito importante para poder brindarle al usuario de Windows Phone, una experiencia agradable, es determinar si su dispositivo esta conectado o no a Internet, hay variados articulos en la red que pueden probar, uno de ellos es este que incluso viene acompanado de un proyecto, es un ejemplo utilizado por Nokia, lamentablemente no funciona o al menos no pude hacer que funcione correctamente y si observan el codigo es bastante ‘elaborado’ para una tarea que es bastante sencilla.

Entonces decidi usar mi propia aproximacion, debo decir que en mi aplicacion actualmente publicada en internet usa la version de codigo que mostrare mas adelante, por lo que puedo garantizar con certeza de que si funciona, ademas de que este articulo es una continuacion prometida de un articulo anterior, en el que explico como detectar internet en aplicaciones Windows y Web.

La idea se centra nuevamente en usar el NCSI de Microsoft, para la tarea y el codigo es el siguiente:

public void IsNCSIConnected(Action<bool> connected)
{
    try
    {
        var x = (HttpWebRequest)WebRequest.Create("http://www.msftncsi.com/ncsi.txt");
        x.BeginGetResponse((resp) =>
                               {
                                   try
                                   {
                                       var response = (HttpWebResponse) x.EndGetResponse(resp);
                                       connected(response.StatusCode == HttpStatusCode.OK);
                                   }
                                   catch
                                   {
                                       connected(false);
                                   }
                               }, null);
    }
    catch (Exception)
    {
        connected(false);
    }
}

Como pueden observar el codigo se basa en la utilizacion de un Delegado Action que devolvera el estado de la conexion. Este metodo me resulto muy util pero se complica cuando manejamos escenarios asincronos, porque quierase o no, bloqueara el hilo de ejecucion de la UI. Entonces pense en una variante mas ‘interesante’.

public async Task<bool> IsNCSIConnected()
{
    var req = (HttpWebRequest)HttpWebRequest.Create("http://www.msftncsi.com/ncsi.txt");
    Task<HttpWebResponse> requestTask = Task.Factory.FromAsync(
        req.BeginGetResponse, result =>
                                  {
                                      try
                                      {
                                          return (HttpWebResponse) req.EndGetResponse(result);
                                      }
                                      catch (Exception)
                                      {

                                          return null;
                                      }
                                      
                                  },
        TaskCreationOptions.None);

    return await requestTask.ContinueWith(responseTask =>
                                                           {
                                                               if (responseTask.Result == null) return false;
                                                               return responseTask.Result.StatusCode ==
                                                                      HttpStatusCode.OK;
                                                           });
}

El codigo puede parecer algo mas complicado, sin embargo la utilizacion es mucho mas simple.

Un Saludo

Usando await en un metodo NO asincrono

He recibido varias preguntas relacionadas a este tema, especialmente desde que se popularizo el uso de await y async, muchas personas creen que es algun tipo de caracteristica ‘magica’, cuando en realidad es una consecuencia logica de varias caracteristicas introducidas en la version 4.o del .NET Framework, especialmente de la clase Task. Una duda recurrente es: Como usar await con un metodo NO asincrono.

Supongamos que disponemos de un metodo NO asincrono como el siguiente, que realiza un proceso que puede bloquear el hilo de la interface de usuario, en caso de llamarse desde ahi.

        /// <summary>
        /// This is a blocking call
        /// </summary>
        /// <returns></returns>
        private NetworkInterfaceType GetNetworkInterfaceType()
        {
            var interfaceType = NetworkInterface.NetworkInterfaceType;
            return interfaceType;
        }

Puede haber muchas soluciones, pero la mas simple que puedo recomendar, no necesariamente la mejor es usar el siguiente codigo:

    var interfaceType =await Task.Run(()=>{returnGetNetworkInterfaceType(); });

Obviamente el metodo donde se introduzca la anterior linea, necesariamente debe tener la palabra reservada async.

Un saludo.

Descargar una imagen y codificarla en Base64

Durante el Diplomado de Windows Phone 8, hubo la necesidad de descargar un grupo de imagenes desde una URL y guardarlas, inicialmente la idea podia pasar por guardarlas en una BD pero solo con fines de experimentacion decidi guardar las imagenes en un archivo de texto codificada (encoded) en base64.

Aqui les comparto el metodo asyncrono que utilice para tal finalidad:

        public Task<string> DownloadImageAsync(string url)
        {
            HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url);
            Task<WebResponse> requestTask = Task.Factory.FromAsync(
                req.BeginGetResponse, result => req.EndGetResponse(result),
                TaskCreationOptions.None);

            Task<string> resultTask = requestTask.ContinueWith(responseTask =>
            {
                using (
                    var stream =
                        responseTask.Result.GetResponseStream())
                {
                    int len = (int)stream.Length;
                    byte[] byt = new Byte[len];
                    stream.Read(byt, 0, len);
                    var b64 = System.Convert.ToBase64String(byt);
                    return b64;
                }
            });
            return resultTask;
        }

Como estuve trabajando intensivamente con MVVM, me vi en la necesidad de usar un Convertidor, que aqui se los paso in-extenso:

    public class ImageBase64Converter : IValueConverter
    {

        #region IValueConverter Members
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            string b64Value = (string)value;
            BitmapImage bi = null;
            if (!String.IsNullOrEmpty(b64Value))
            {
                byte[] imageBytes = System.Convert.FromBase64String(b64Value);
                bi = new BitmapImage();
                bi.SetSource(new MemoryStream(imageBytes));
            }
            return bi;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            BitmapImage bi = (BitmapImage) value;

            using (MemoryStream ms = new MemoryStream())
            {
                WriteableBitmap btmMap = new WriteableBitmap(bi.PixelWidth, bi.PixelHeight);
                // write an image into the stream
                Extensions.SaveJpeg(btmMap, ms, bi.PixelWidth, bi.PixelHeight, 0, 100);

                int len = (int)ms.Length;
                byte[] byt = new Byte[len];
                ms.Read(byt, 0, len);
                var b64 = System.Convert.ToBase64String(byt);
                return b64;
            }
        }
        #endregion
    }

Saludos

Simplificando las cosas con Events, EventHandlers & EventArgs

Los eventos son una parte importante dentro del framework .NET, recuerdese que son la implementacion del patron observador, por cierto la implementacion mas elegante que puede hacerse. Sin embargo cuando usamos eventos necesitamos pasar o mas exactamente, informar con ciertos parametros hacia el manejador de eventos, observece los siguientes trozos de codigo:

Supongamos que tenemos una situacion en la que queremos informar del cambio de nombre, algo simple es el siguiente codigo, con este codigo lo maximo que se puede hacer es saber si se ha cambiado el nombre o no

public event EventHandler NombreCambiado;

public void OnNombreCambiado(EventArgs e)
        {
            EventHandler handler = NombreCambiado;
            if (handler != null) handler(this, e);
        }

Que ocurre si queremos informar cual es el nuevo nombre?, las cosas se empiezan a complicar pues quiza queremos usar el siguiente codigo:

        public event EventHandler<EventArgs> NombreCambiado;

        public void OnNombreCambiado(EventArgs e)
        {
            EventHandler<EventArgs> handler = NombreCambiado;
            if (handler != null) handler(this, e);
        }

Sin embargo EventArgs no soporta el paso de parametros, lo recomendado es crear una clase derivada de EventArgs, en el caso del ejemplo la clase se llama NombreEventArgs, como se muestra en el siguiente codigo:

    public class NombreEventArgs: EventArgs
    {
        public string Nombre { get; set; }
        public NombreEventArgs(string nombre)
        {
            Nombre = nombre;
        }
    }

        public event EventHandler<NombreEventArgs> NombreCambiado;

        public void OnNombreCambiado(string nombre)
        {
            EventHandler<NombreEventArgs> handler = NombreCambiado;
            if (handler != null) handler(this, new NombreEventArgs(nombre));
        }

Aqui surge el punto que cada vez que querramos pasar/devolver un parametro de algun tipo, debemos crear una nueva clase? En un principio puede parecer que si, pero a medida que va creciendo una aplicacion podemos encontrarnos con muchas clases que son innecesarias, entonces cual puede ser la solucion?

Crear una clase generica de EventArgs, el resultado, una clase llamada DataEventArgs<T> que la utilizo practicamente en todo proyecto que tengo:

    public class DataEventArgs<T>: EventArgs
    {
        public T Data { get; set; }

        public DataEventArgs(T data)
        {
            Data = data;
        }
    }

La utilizacion?, utilizando el anterior ejemplo:

        public event EventHandler<DataEventArgs<string>> NombreCambiado;

        public void OnNombreCambiado(string nombre)
        {
            EventHandler<DataEventArgs<string>> handler = NombreCambiado;
            if (handler != null) handler(this, new DataEventArgs<string>(nombre));
        }

Saludos.

Remover HTML tags

A raiz de un requerimiento, en el Diplomado de Windows Phone 8, que nos pedia consumir un servicio, que devolvia HTML y colocar el contenido recuperado del servicio, como texto plano, en la aplicacion Windows Phone, tuve que buscar la mejor manera de eliminar los tags HTML, encontre este excelente articulo, y el codigo que pongo a continuacion:

/// <summary>
    /// Methods to remove HTML from strings.
    /// </summary>
    public static class HtmlRemoval
    {
        /// <summary>
        /// Remove HTML from string with Regex.
        /// </summary>
        public static string StripTagsRegex(string source)
        {
            return Regex.Replace(source, "<.*?>", string.Empty);
        }

        /// <summary>
        /// Compiled regular expression for performance.
        /// </summary>
        static Regex _htmlRegex = new Regex("<.*?>", RegexOptions.Compiled);

        /// <summary>
        /// Remove HTML from string with compiled Regex.
        /// </summary>
        public static string StripTagsRegexCompiled(string source)
        {
            return _htmlRegex.Replace(source, string.Empty);
        }

        /// <summary>
        /// Remove HTML tags from string using char array.
        /// </summary>
        public static string StripTagsCharArray(string source)
        {
            char[] array = new char[source.Length];
            int arrayIndex = 0;
            bool inside = false;

            for (int i = 0; i < source.Length; i++)
            {
                char let = source[i];
                if (let == '<')
                {
                    inside = true;
                    continue;
                }
                if (let == '>')
                {
                    inside = false;
                    continue;
                }
                if (!inside)
                {
                    array[arrayIndex] = let;
                    arrayIndex++;
                }
            }
            return new string(array, 0, arrayIndex);
        }
    }

El detalle no termina en copiar y usar el codigo, sino en la necesidad de usar esta clase en un Portable Library, lo que me hizo caer en cuenta que la opcion de compilar las expresiones regulares no estan soportadas en este tipo de librerias de clase (por eso pueden ver que el enumerador tiene un color un tanto diferente en el codigo anterior)

En fin, el metodo utilizado fue: StripTagsCharArray.

Un saludo.

Json Serializacion/Deserializacion

Durante las ultimas cuatro semans estuve participando del Diplomado de Windows Phone 8 que se organizo desde Mexico, con la indispensable presencia de Rodrigo Diaz Concha. Demas esta decir que estuvo genial, la cantidad de cosas recibidas y es mi intencion devolver a la comunidad algunas cosas aprendidas.

Existen situaciones donde es necesario serializar o deserializar un objeto a JSON. Se que existen librerias que lo hacen mas eficientemente, aqui pueden encontrar una comparativa muy interesante de ellas. Pero mi intencion es mantenerlo simple y no necesariamente eficiente (por ahora)

public class JsonHelper
{
/// <summary>
///
JSON Serialization
/// </summary>
public static string JsonSerializer<T>(T t)
{
string result = string.Empty;
using (MemoryStream stream = new MemoryStream())
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
serializer
.WriteObject(stream, t);
stream
.Position = 0;
using (StreamReader sr = new StreamReader(stream))
{
result
= sr.ReadToEnd();
}
}

return result;
}

/// <summary>
///
JSON Deserialization
/// </summary>
public static T JsonDeserialize<T>(string jsonString)
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString));
T obj
= (T)serializer.ReadObject(ms);
return obj;
}
}

Saludos

Episodio 6 – Arquitectos.NET Podcast

Las múltiples ocupaciones retrasaron su publicación pero lo prometido es deuda, en esta ocasión, les entregamos la segunda parte de la grabación acerca del tema Bases de Datos NoSQL, conversamos acerca de:

  • Una recapitulación rápida de lo hablado anteriormente
  • Revisión de los Modelos distribuidos
  • Normalización/Des normalización
  • Patrones de Diseño
  • Map/Reduce
  • Persistencia Poliglota (CQRS)

Para aquellas personas que deseen bajar el mp3, aquí se encuentra el enlace.

Esperamos que les haya agradado y quisiéramos escuchar sus comentarios y sugerencias, es perfectamente valido hacerlo de manera privada a nuestros email (dnimrevo@gmail.com y enrique@ortuno.net).

Saludos.

Usando async/await en programas de consola

Hoy intentando preparar algunos ejemplos de entrenamiento me tope con una interesante curiosidad de asyn/await y es que usarlo en un programa de consola, probablemente la solucion que muestre es evidente para los con mas experiencia pero como siempre vale aclararlo, esto lo escribo para los que estamos metiendonos mas con async y await.

La idea es que tengo este bloque de codigo que contiene un metodo asincrono que quiero invocar usando await, pero como saben para usar await el metodo que lo contiene tiene que estar marcado con async, entonces se me ocurrio hacer esto:

   1:  class Program
   2:      {
   3:          static async void Main(string[] args)
   4:          {
   5:              var client = new RestClient("https://qrng.anu.edu.au");
   6:              // client.Authenticator = new HttpBasicAuthenticator(username, password);
   7:   
   8:              var request = new RestRequest("/API/jsonI.php", Method.GET);
   9:              request.AddParameter("length", "1"); 
  10:              request.AddParameter("size", "1"); 
  11:              request.AddParameter("time", "1365981445598"); 
  12:              request.AddParameter("type", "uint8");
  13:             
  14:   
  15:              var rx = await ExecuteTaskAsync(client, request, new CancellationToken());
  16:              Console.WriteLine("Showing content...");
  17:              Console.WriteLine(rx.Content);
  18:   
  19:              Console.ReadKey();
  20:          }
  21:   
  22:          private static async Task<IRestResponse> ExecuteTaskAsync(RestClient _restClient, RestRequest request, CancellationToken cancellationToken)
  23:          {
  24:              var taskCompletionSource = new TaskCompletionSource<IRestResponse>();
  25:   
  26:              var asyncHandle = _restClient.ExecuteAsync(request, r => taskCompletionSource.SetResult(r));
  27:   
  28:              using (cancellationToken.Register(() => asyncHandle.Abort()))
  29:              {
  30:                  return await taskCompletionSource.Task;
  31:              }
  32:          }
  33:      }

Pero al intentar colocar el async en la linea 3 se obtiene un error de compilacion que dice:

“an entry point cannot be marked with the ‘async’ modifier “

Para solucionar esto simplemente cambie el codigo agregando un metodo adicionar que realiza la llamada asincrona, removiendo la palabra reservada async y usando el WaitAll, tal como se muestra a continuacion:

   1:  class Program
   2:      {
   3:          static void Main(string[] args)
   4:          {
   5:              var task = OnlyCaller();
   6:              Task.WaitAll(task);
   7:              Console.ReadKey();
   8:          }
   9:   
  10:          private static async Task OnlyCaller()
  11:          {
  12:              var client = new RestClient("https://qrng.anu.edu.au");
  13:              // client.Authenticator = new HttpBasicAuthenticator(username, password);
  14:   
  15:              var request = new RestRequest("/API/jsonI.php", Method.GET);
  16:              request.AddParameter("length", "1"); 
  17:              request.AddParameter("size", "1"); 
  18:              request.AddParameter("time", "1365981445598"); 
  19:              request.AddParameter("type", "uint8"); 
  20:   
  21:              var rx = await ExecuteTaskAsync(client, request, new CancellationToken());
  22:              Console.WriteLine("Showing content...");
  23:              Console.WriteLine(rx.Content);
  24:          }
  25:   
  26:          private static async Task<IRestResponse> ExecuteTaskAsync(RestClient _restClient, RestRequest request, CancellationToken cancellationToken)
  27:          {
  28:              var taskCompletionSource = new TaskCompletionSource<IRestResponse>();
  29:   
  30:              var asyncHandle = _restClient.ExecuteAsync(request, r => taskCompletionSource.SetResult(r));
  31:   
  32:              using (cancellationToken.Register(() => asyncHandle.Abort()))
  33:              {
  34:                  return await taskCompletionSource.Task;
  35:              }
  36:          }
  37:      }

 

Espero que les sea util,

 

Saludos