Oktoberfest

Oktoberfest -> Novetats Mobile Services

Oktoberfest

Estem planificant una nova trobada per finals de Octubre (en principi el proper divendres 31 d’Octubre).

La idea es veure les novetats de AZURE Mobile Services, que es un Backend per a aplicacions multiplataforma (iOS, Android, Windows, Javascript o Mac).

  • Integració oAuth amb Facebook, Twitter, Google o Microsoft accounts.
  • Repositori de dades (SQL o MongoDb)
  • Sincronització offline (mola!)
  • API REST
  • Task Scheduler
  • Personalitzar el mobile service C#
  • Si tenim temps podem veure algo de Push & realtime

Lloc: A la sala del 2º pis de l’edifici ‘La llacuna’
Hora: Comencem a les 18h30 fins les 20h00/20h30

Després unes birres i sopar qui s’apunti :)

Materials event Office365 Rest API

O365

Hola de nou,

Us deixo els materials de l’event que vàrem fer divendres passat sobre la nove API Rest per accedir a Office365. Val a dir que tot i que li falten un parell de funcionalitats (que vindran en els propers mesos) per fi tenim una alternativa plenament funcional als antics Exchange Web Services (EWS). Amb l’avantatge de que és més molt més rápida (x20 com a mínim).

O365RestApiLogin

És important senyalar que el trick és paginar entre els resultats que ens retorna la API, com varem veure en el projecte d’exemple:

public static async Task<IEnumerable<Contact>> GetContacts()
{
    var cnames = new List<Contact>();
    var page = 0;
    var client = await EnsureClientCreated();
    var contactsResults = await client.Me.Contacts.Where(p => p.DisplayName != null).ExecuteAsync();
    var cl = contactsResults.CurrentPage.ToList();
    cnames.AddRange(addContactsCurrentPageToList(cl));
    while(cl.Count > 0)
    {
        page++;
        contactsResults = await client.Me.Contacts.Where(p => p.DisplayName != null).Skip(50 * page).ExecuteAsync();
        cl = contactsResults.CurrentPage.ToList();
        cnames.AddRange(addContactsCurrentPageToList(cl));
    }
    return cnames;
}

private static List<Contact> addContactsCurrentPageToList(
    List<IContact> contactsResults)
{
    var contacts = new List<Contact>();
    contacts.AddRange(contactsResults.Select(p => new Contact()
    {
        BusinessPhone1 = p.BusinessPhone1,
        CompanyName = p.CompanyName,
        DisplayName = p.DisplayName,
        EmailAddress1 = p.EmailAddress1,
        HomePhone1 = p.HomePhone1,
        JobTitle = p.JobTitle,
        Manager = p.Manager,
        MobilePhone1 = p.MobilePhone1,
        Title = p.Title
    }));
    return contacts;
}

O365RestAPiContracts

Aquí teniu el projecte publicat al meu Onedrive.

Enjoy! :)

Webcast: Mejora el rendimiento con Programación Paralela

El próximo 29 de Noviembre montaremos un webcast con los chicos de SecondNug sobre programación paralela.

banner_parallel

La idea es empezar mostrando el porqué de la programación paralela: Que es? Cómo hemos llegado a esta singularidad? Y en que casos puede sernos útil -que son muchos más de los que os podéis imaginar-. Además, como vais a ver en el webcast esto cada vez va a ir a más. Y no sólo a largo plazo… pero no os quiero avanzar mucho más, mejor ya lo veréis :-D

image image

A partir de las 19h30 empezaremos nuestro viaje por las principales características de la nueva Task Parallel Library (TPL). Comenzaremos por una breve introducción para asentar algunos conceptos (y para picaros el gusanillo), y posteriormente pasaremos a hacer demos por un tubo. Que al fin y al cabo somos developers y es lo que nos gusta!

foro_parallel

Puedes registrarte aquí:
https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032498453&Culture=es-AR 

Nos vemos pronto,

L

PD – Mi idea era llamarlo ‘Paralelízate o muere’ pero tal vez era un poco demasiado bestia… o no? Júzgalo tu mismo :-)

Sharpwhere over the rainbow…

…skies are blue :-)

Si, se que el título del post está ‘pillado’ con pinzas, pero de lo que trata este post es de “cómo utilizar una brocha para pintar el interior de un control con varios niveles de degradado“, o sea “pintar un control Label con los colores del arco iris” :-D

Que? Ya habéis terminado de reíros?

Pues ahora os cuento el porqué se me ha ocurrido todo esto: Resulta que un proyecto en el que estoy trabajando, se muestran unas barras de progreso de color azul que indican el % de realización de unos presupuestos. Después de mirarlas un rato y ver lo ‘sosas’ que quedaban, he pensado que le podía dar un toque de color, aprovechando que pronto va a ser el día del orgullo friki.

mojo1

A que es bonito, verdad? :-)

Vale, pues hacer esto con WPF es trivial mediante GradientStops, pero, oooohhhh… este proyecto es WinForms. Pero tranquilos, el viejo y bueno namespace ‘System.Drawing.Drawing2D’ dispone de alguna sorpresa, como la clase ColorBlend, que permite definir un array de colores y posiciones para realizar degradados de colores. Anda mira, me ha salido un pareado! :-D

Total, que partiendo del evento Paint de cualquier control (en el que se obtienen como argumentos el contexto gráfico y el rectángulo del área a pintar), he creado una pequeña clase que permite especificar los distintos colores de degradado para el mismo:


public class MultiGradientRectangle
{
    public Graphics Graphics { get; set; }
    public Rectangle Rectangle { get; set; }
    public List<Color> ColorPoints { get; set; }
    public int PercentCompleted { get; set; }

    public MultiGradientRectangle(Graphics graphics, Rectangle rectangle)
    {
        Graphics = graphics;
        Rectangle = rectangle;
        ColorPoints = new List<Color>();
    }

    public void DrawMultiGradientRectangle()
    {
        if (PercentCompleted == 0) return;
        if (ColorPoints.Count == 0) return;
        List<float> myPositions = new List<float>();
        float colordistance = 1f / (ColorPoints.Count - 1f);
        for (int i = 0; i < ColorPoints.Count; i++)
        {
            myPositions.Add(colordistance * i);
        }
        ColorBlend blend = new ColorBlend();
        blend.Colors = ColorPoints.ToArray();
        blend.Positions = myPositions.ToArray();
        using (LinearGradientBrush brush = new LinearGradientBrush(
            Rectangle, Color.Black, Color.White, 0, false))
        {
            brush.InterpolationColors = blend;
            Graphics.FillRectangle(brush, Rectangle);
        }
        //algo falta aquí... .-)
    }
}

Ahora creamos un formulario con un control pictureBox (en realidad puede ser cualquiera) y nos suscribimos a su evento Paint.


public Form1()
{
    InitializeComponent();
    pictureBox1.Paint += pictureBox1_Paint;
}

void pictureBox1_Paint(object sender, PaintEventArgs e)
{
    drawMultiGradient(e.Graphics, e.ClipRectangle, 50);
}

private static void drawMultiGradient(Graphics g, Rectangle rect, int percent)
{
    MultiGradientRectangle mgrect = new MultiGradientRectangle(g, rect);
    mgrect.PercentCompleted = percent;
    mgrect.ColorPoints.Add(Color.Red);
    mgrect.ColorPoints.Add(Color.Orange);
    mgrect.ColorPoints.Add(Color.Yellow);
    mgrect.ColorPoints.Add(Color.LightGreen);
    mgrect.ColorPoints.Add(Color.Green);
    mgrect.DrawMultiGradientRectangle();
}

Así, podemos crear tantos puntos intermedios como queramos, sólo tenemos la limitación del buen gusto.

Sin embargo falta algo, verdad? Efectivamente, en la captura de pantalla puede verse perfectamente que las barras de progreso se ‘rellenan’ sólo hasta el porcentaje alcanzado. Si es un 0% no hay degradado, si es un 50% sólo hasta la mitad, y así…

Como veis, falta un fragmento de código en el método DrawMultiGradientRectangle. Os dejo como ejercicio mostrar únicamente el relleno hasta el % especificado mediante la propiedad ‘PercentCompleted’. A ver que solución es la más chula ;-)

Un saludo desde Andorra, nos vemos!

PD – Podéis decir lo que queráis acerca del diseño, se admiten todo tipo de críticas (otra cosa es que os haga caso :-P)

[HowTo] Obtener el valor de una propiedad de usuario en LDAP

El motivo

A raíz de una pregunta que me lanzó ayer mi colega Ricardo, hoy vamos a ver cómo obtener el valor de una propiedad de un usuario del directorio activo de la organización. Esto de por si, no tiene ningún secreto, basta con utilizar las clases contenidas en el namespace System.DirectoryServices. Lo que sí tenemos que tener muy claro, es el nombre de esa propiedad dentro del esquema del LDAP de nuestra organización.

GetPropADUser

Por ejemplo, para obtener el mail, la propiedad a utilizar es mail, obvio, no? Sin embargo en otras ocasiones no siempre es así. Por ejemplo, el nombre de la propiedad que nos devuelve el teléfono de un usuario es telephoneNumber, el código postal es postalCode, pero por ejemplo la propiedad que nos devuelve los apellidos, no es surname, sino sn, o el nombre del usuario está definido como sAMAccountName. En resumen, muchas de las propiedades están definidas con unos nombres… como decirlo? Muy cachondos :-P

Obtener los atributos de una clase

A todo esto ¿Cómo podemos obtener los nombres de los atributos de un usuario del LDAP en tiempo de ejecución? Easy –> Buscando la definición de la clase user en el esquema de nuestro LDAP y obteniendo su catálogo de propiedades (básicas + extendidas):

public static List<string> GetUserLDAPProperties(string LDAPUrl)
{
    List<string> properties = new List<string>();
    ActiveDirectorySchema adSchema = ActiveDirectorySchema.GetCurrentSchema();
    ActiveDirectorySchemaClass userSchema =
        default(ActiveDirectorySchemaClass);
    ActiveDirectorySchemaPropertyCollection propertiesCollection =
        default(ActiveDirectorySchemaPropertyCollection);
    userSchema = adSchema.FindClass("user");
    propertiesCollection = userSchema.MandatoryProperties;
    foreach (ActiveDirectorySchemaProperty prop in propertiesCollection)
    {
        properties.Add(prop.Name);
    }
    propertiesCollection = userSchema.OptionalProperties;
    foreach (ActiveDirectorySchemaProperty prop in propertiesCollection)
    {
        properties.Add(prop.Name);
    }
    properties.Sort();
    return properties;
}

De este modo obtenemos los nombres de las propiedades, con lo que ya sabemos los nombres de los atributos de un usuario de nuestro LDAP. Así pues, a partir del nombre de la propiedad que deseamos obtener, del identificador de seguridad de un usuario, y del nombre del dominio, ahora si vamos a ser capaces de obtener el valor de ese atributo para un usuario de nuestro LDAP (siempre que tenga ese atributo definido, claro):

public static string GetNTAccountProperty(string sid, string domain, string propertyToLoad)
{
    if (string.IsNullOrEmpty(sid)) throw new ArgumentNullException();
    if (string.IsNullOrEmpty(domain)) throw new ArgumentNullException();
    if (string.IsNullOrEmpty(propertyToLoad)) throw new ArgumentNullException();
    string ldapDomainName = GetLDAPDomainName(domain);
    using (DirectoryEntry entries = new DirectoryEntry(ldapDomainName))
    {
        string filter = string.Format(
            "(&(objectCategory=person)(objectClass=user)(objectSID={0}))", sid);
        DirectorySearcher searcher = new DirectorySearcher(entries, filter);
        searcher.PropertiesToLoad.Add(propertyToLoad);
        searcher.PropertiesToLoad.Add("objectSID");
        SearchResult result = searcher.FindOne();
        if (!result.Properties.Contains(propertyToLoad))
            throw new ActiveDirectoryObjectNotFoundException(
                string.Format("Property '{0}' not found on NTAccount '{1}'",
                propertyToLoad, sid));
        return result.Properties[propertyToLoad][0].ToString();
    }
}

Métodos de apoyo

Muchas de éstos métodos utilizan el nombre de nuestro LDAP en el siguiente formato: LDAP://DC=local,DC=miempresa,DC=com

Así que aquí tenéis una función que lo obtiene a partir del nombre del dominio:

public static string GetLDAPDomainName(string domainName)
{
    StringBuilder sb = new StringBuilder();
    if (string.IsNullOrEmpty(domainName)) throw new ArgumentNullException();
    string[] dcItems = domainName.Split(".".ToCharArray());
    sb.Append("LDAP://");
    foreach (string item in dcItems)
    {
        sb.AppendFormat("DC={0},", item);
    }
    return sb.ToString().Substring(0, sb.ToString().Length - 1);
}

Que a su vez se obtiene de este otro método:

public static string GetDomainName()
{
    return IPGlobalProperties.GetIPGlobalProperties().DomainName;
}

Proyecto de ejemplo

Hay algunas cosillas más, como la obtención de los usuarios del LDAP que (para no hacer el post más ‘tocho’ :-P) no hemos visto en el post. Podéis descargar el proyecto de ejemplo completo desde skydrive en esta ubicación:

http://cid-f3a970280830b5fe.office.live.com/self.aspx/MSDN%20Samples/TestLDAP.zip 

Uffff… al final me ha salido un post más largo de lo que yo quería, pero bueno, espero que os sirva de algo :-)

Saludos desde Andorra,

[Video] Parallel Series 01–Bases

Hola a tots,

Acabo de publicar un preview del primer dels (al menys) 6 vídeos sobre programació paral·lela amb .NET Framework 4.0.

De moment el podeu trobar aquí a youtube (encara no està publicat a Channel9), ja que encara és possible que canvií alguna cosa.

Com és el primer de la sèrie us agrairia una mica de feedback, que us sembla, coses a millorar, etc.

Merci i espero que us agradi :-)

[Debate] Nombre de Namespaces en métodos extensores ¿Y tu que opinas?

Ayer, a raíz de un post del colega Javier Torrecilla sobre métodos extensores, unos cuantos de nosotros entre los que estaban el propio Javier y Jorge Serrano nos enzarzamos en una discusión en twitter acerca del mejor modo de declarar nuestros métodos extensores.

Pongamos un ejemplo: Supongamos que queremos crear un método extensor para comprobar si un valor está entre dos valores (el clásico between de toda la vida).

Agrego una clase llamada ExtensionMethods a mi proyecto, o a otro proyecto mi solución y agrego este código:


namespace CustomExtensions
{
    public static class ExtensionMethods
    {
        public static bool Between<T>(this T @value, T min, T max) where T : IComparable<T>
        {
            return @value.CompareTo(min) >= 0 && @value.CompareTo(max) <= 0;
        }
    }
}

Suponiendo que estamos en un proyecto de tipo WinForms, si queremos utilizar este método extensor sobre un valor de tipo int basta con ir a cualquier formulario y llamar al método between sobre un valor de este tipo. Por ejemplo:

EM1

Oops! Que pasa? Por que no aparece el método extensor? Bueno, como ya os habréis dado cuenta el método extensor está declarado dentro de un namespce llamado ‘CustomExtensions’, que es distinto al namespace del formulario en el que lo estoy probando, con lo que no podemos usarlo directamente si previamente no hacemos un using:

Vale, ahora si que aparece:

using CustomExtensions;

EM2

Bien. Esto en si no es nada del otro mundo, pero la cuestión es que si deseamos evitar declarar el using (tenéis que pensar que este método extensor lo podéis reutilizar en 1000 proyectos distintos), no tenemos otra opción que:

  1. Declarar el método extensor en un namespace que se llame igual que el namespace en el que se va a usar.
  2. Declarar el método extensor en un namespace que se llame igual que el namespace del tipo que estamos extendiendo.
  3. Pasar de todo y llamarlo al namespace como queramos, y que a la hora de usarlo debamos usar un using para agregarlo.

Particularmente soy partidario del segundo punto, de modo que si vamos a extender elementos de tipo IComparable, en lugar de usar el namespace ‘CustomExtensions’ prefiero usar el nombre del namespace que contiene la definición de este tipo, o sea ‘System’:


namespace System
{
    public static class ExtensionMethods
    {
        public static bool Between<T>(this T @value, T min, T max) where T : IComparable<T>
        {
            return @value.CompareTo(min) >= 0 && @value.CompareTo(max) <= 0;
        }
    }
}

Pero ese es mi punto de vista, tu que opinas? Twitteros manifestaos! :-)