[IT] Outlook.com con dominio propio

Hola,

Hace unos días q llevo intentando migrar a Outlook.com para probar que tal va.

He leído algunos POST sobre cómo conectar GMAIL a Outlook y así estar al día sobre lo que por allí recibimos desde una única interfaz. Si aún no sabes cómo hacerlo, puedes  ver este post de Pilar con video incluido.

El problema que algunos nos encontramos es que en todos los casos se usa nuestra dirección de Outlook como dirección de re-envío. Para los que usamos cuentas personales (dominios propios: odelvalle.com) para acceder a live, hacer esto  implica re-enviar todo el tráfico de nuestra cuenta GMail a nuestro servidor de correo.

Para evitar esto, intenté cambiar mi cuenta outlook pero me avisó que perdería la conexión de todos los dispositivos asociados a esa cuenta live (malo malo). Busqué si se podía crear una nueva cuenta pero eso implicaría tener 2 accesos a live, una con mi correo personal y la otra con la nueva cuenta outlook (esto tampoco me convence)

Dedicando un ratico cada mañana a buscar posibles soluciones, hoy encuentro una: :

Untitled

Crear un alias en outlook.com es la manera que tenemos de unir/asociar varias direcciones de correo electrónico a una sola. 

Untitled1

Al crear el Alias, Outlook.com te enviará un correo de verificación a tu cuenta personal (live) para asegurarse que el Alias está correctamente asociado.

Untitled2

y ya estamos listos. Podemos seguir los pasos que nos cuenta Pilar en su post y utilizar el alias de outlook como dirección de re-envío, de esta forma los correos de GMAIL no pasarán por nuestro pequeño e indefenso servidor e irán directamente al grande de Outlook.com. Sonrisa

Salu2

POO–Responsabilidades

“Hay una diferencia entre programar orientado a objetos y pensar orientado a objetos”

CNX-B4WDebatiendo hoy en el trabajo sobre la funcionalidad que debería tener una toolsbox, salió uno de esos temas que me encantan. ¿Dónde debe estar el código asociado a un clic de un botón?

Responsabilidades

Mucho más allá de si la pregunta se responde aplicando un Chain of Responsibility Pattern, dentro se esconde uno de los pilares de la POO, la Especialización. Los objetos mientras mayor sea su especialización, mejor podremos definir su comportamiento.

¿Qué quiere decir esto? Pues que la responsabilidad de cada objeto debe ser solo, la que permita cumplir los objetivos por el cual fue creado.

Un avión vuela (por suerte). Nosotros desde fuera vemos un conjunto, pero dentro del avión hay miles de objetos que tienen una responsabilidad específica y que entre todos, hace que el avión vuele. Creo que excepto en las teles de la antigua URSS (le quitabas piezas y seguían funcionando), todo objeto tiene una responsabilidad que permite lograr una funcionalidad superior.

¿Que es una toolsbox? pues un panel de botones y nada más. Cuando compramos un panel de botones este no incluye para qué se usa cada botón o qué hace cada botón. Si compramos un interruptor eléctrico, este por si solo no apaga ni enciende la luz, incluso, puede llegar a realizar funciones explosivas si conectas incorrectamente los cables (que me pregunten a mi con 11 años la que lié).

Nuestra toolsbox, tiene botones (como casi todas) y el objetivo que cumplirá cada botón debería ser independiente a la misma. Un botón “dentro de la toolsbox” tiene estados cuyos cambios son notificados al exterior para quien quiera hacer algo que lo haga.

Lo mismo pasa con nuestro avión, mueves los mandos de vuelo y giras, esto no ocurre porque las aletas y el mando sean un único e inseparable objeto, sino porque el mando cambia de estado y notifica a todo aquel que pueda estar interesado para que haga algo. Las aletas y seguramente muchos objetos más dentro de un avión, están escuchando continuamente para saber si los mandos de vuelo han cambiado de posición(estado).

Vean que para definir cual debe ser la responsabilidad de mi  toolsbox, me he basado en todo momento en ejemplos de la vida real.

En el evento que di sobre POO en SecondNug (aquí tenéis los apuntes) cuando se analizaba la crisis del software, se definió como objetivo de la programación orienta a objetos el acercamiento del ordenador al problema y no del problema al ordenador, lo cual significa que debemos intentar en todo momento modelar los problemas existentes en la vida real analizándolo como lo que son, cosas que ocurren en la realidad. Esto era y seguramente aún es, el paradigma de la POO.

El otro día leía un artículo de Eduard sobre knockout y había una línea de texto que decía: «el código javascript es totalmente ignorante del DOM y trabaja tan solo con el viewmodel. Separación de responsabilidades.” ¡Atentos! que en este artículo se habla de separar la responsabilidad entre el HTML y el Javascript… (si digo yo esto en una entrevista de trabajo hace unos años, ya me dirán ustedes que hubieran pensado de mi)

Seguramente hoy por hoy aún queda mucho por hacer, pero da gusto como cada vez más intentamos llevar a la más mínima expresión la separación de responsabilidades. Mi opinión es que mientras menor sea la responsabilidad de un objeto, siempre que cumpla su objetivo, mejor y más fácil será de mantener.

Por cierto, para no dejarles sin saber, la toolsbox terminó con N botones que no saben lo que hacen pero que notifican a quien pueda interesar los estados de onBeforeClick y onClick. (espero no ser yo quien tenga que conectarla) Sonrisa

Salu2

Mensajes de browser a browser (Web Socket)

ws_tornadoHe estado trabajando últimamente en un proyecto en el que necesitaba comunicación entre instancias distintas de browsers en tiempos lo más real posible.

La solución se desprende, Web Socket con HTML5 Sonrisa

La lógica que necesitamos en el servidor es simple, transmitir un mensaje que viene de un cliente, al resto de los clientes conectados.

En la parte del servidor quiero la menor lógica posible, así podré reutilizarlo en distintos proyectos. Los mensajes van de clientes a clientes, por lo que la responsabilidad del servidor en este caso debe ser solamente la de comunicación.

Para implementar el servidor he usado Fleck, un Web Socket que ya existe para NET y el cual recomiendo muchísimo, un código claro y fácil de entender si te pica la curiosidad y quieres conocer internamente cómo funciona.

Server

De momento vamos a crear una aplicación de consola para hospedar a nuestro Socket Server.

class Program
{
    static void Main()
    {
        FleckLog.Level = LogLevel.Debug;

        var socketManager = new MessagesWebSocket();
        socketManager.Start();

        Console.ReadLine();

        socketManager.Close();
    }
}

La clase MessagesWebSocket tendría:

class MessagesWebSocket
{
    private readonly List<IWebSocketConnection> _allSockets;
    private readonly WebSocketServer _server;


    public MessagesWebSocket()
    {
        _allSockets = new List<IWebSocketConnection>();
        _server = new WebSocketServer(ConfigurationManager.AppSettings["socketServer"]);
    }

    public void Start()
    {
        _server.Start(socket =>
        {
            socket.OnOpen = () =>
            {
                Console.WriteLine("Open client connection!");
                _allSockets.Add(socket);
            };

            socket.OnClose = () => _allSockets.Remove(socket);
            socket.OnMessage = message => _allSockets.Where(s=> s != socket).ToList().ForEach(s => s.Send(message));
        });
    }

    public void Close()
    {
        _allSockets.ForEach(s => s.Close());
        _server.ListenerSocket.Close();
    }
}

Si has trabajado con Socket verás que no hay mucha diferencia a lo que se hacía hasta ahora, incluso, la clase WebSocketServer de Fleck usa internamente System.Net.Sockets.

Nuestra clase MessagesWebSocket tiene dos métodos, Start & Stop.

Start nos permite abrir la conexión y quedarnos a la escucha de cualquier petición de conexión de algún cliente. Cuando un cliente previamente conectado envía un mensaje al servidor, este simplemente toma el mensaje tal cual y lo envía al resto de clientes conectados.

El servidor no interviene en absoluto en la estructura del mensaje que se envía, justamente lo que necesitamos. Entender los mensajes que se envían los clientes será siempre responsabilidad de ellos.

Client

Si hablamos de clientes WEB, la moda en comunicación se llama JSON! Sonrisa Así que vamos a hacer que este sea el formato que usen los mensajes enviados entre clientes.

Para que todo el tema de web socket y json nos quede fuera de la lógica de cualquier página o proyecto, vamos a encapsular toda la funcionalidad dentro de un objeto en Javascript que nos permita enviar y recibir mensajes sin importarnos cómo.

var WebSocketHelper = function (server, onMessage, onError)
{
    var w = window;
    var connection;

    var reciveData = onMessage || false;
    var error = onError || false;

    // if user is running mozilla then use it's built-in WebSocket
    w.WebSocket = w.WebSocket || w.MozWebSocket;

    // open connection
    try
    {
        connection = new w.WebSocket(server);
    }
    catch (connErr)
    {
        if (error) error("Open connection error: " + connErr);
        return;
    }

    // only for debug propose
    connection.onopen = function ()
    {
        //alert('Connected.');
    };

    connection.onmessage = function (d)
    {
        var result = jQuery.parseJSON(d.data);
        if (reciveData) reciveData(result);

        return false;
    };

    connection.onerror = function (wsErr)
    {
        if (error) error("Connection error: " + wsErr);
        connection = null;
    };

    this.SendCommand = function (obj)
    {
        try
        {
            var jsonString = JSON.stringify(obj);
            connection.send(jsonString);
        }
        catch (sendErr)
        {
            if (error) error("Send message error: " + sendErr);
        }
    };
};

Vamos por parte.

1- Al objeto WebSocketHelper le pasamos tres parámetros: la dirección del servidor, una función (opcional) que se ejecutará cuando nos llegue un nuevo mensaje y otra función (también opcional) que se ejecutará si encontramos algún error.

2- Instanciamos un nuevo objeto WebSocket, y aquí entramos en las diferencias entre browsers de toda la vida. Firefox tiene un objeto MozWebSocket mientras Chrome e Internet Explorer (v10) usan WebSocket.

3- Luego de instanciado el socket, intentamos abrir la conexión con el servidor, si todo sale bien, estamos listos para enviar y recibir datos mediante el socket.

4- El evento onmessage es quien me permite capturar los mensajes que llegan desde el servidor. La función asociada a este evento toma el mensaje recibido y lo transforma a un objeto javascript usando jQuery.parseJSON. Al tener la información recibida como objeto javscript, se ejecuta la función que hemos pasado al WebSocketHelper pasando como parámetro el objeto recibido.

5- Para enviar un objeto al servidor el proceso es parecido. Se usa la función pública SendCommand y se pasa como parámetros el objeto a enviar. Esta función internamente convierte el objeto en string y lo envía mediante el socket al servidor.

¿Cómo funciona esto desde una página?

Primero que todo hay que llegar a un acuerdo entre clientes, podemos enviar cualquier objeto javascript mediante el servidor pero es necesario que los clientes sepan de que va el asunto, porque de lo contrario sería como pedir una cerveza y que de pronto te lleguen melones, quesos, tomates, gambas y sandias ( y lo peor es que intentes algo porque creas que son cervezas).

En mi caso he usado una estructura de objetos muy simple. Internamente cada objeto que envío tiene una propiedad llamada command que define el tipo de mensaje que es.

var commands = { stop: "stop", start: "start", game: "game", reset: "reset", gameover: "gameover" };

Inicializando el socket server y recibiendo datos desde el servidor:

var socket = new WebSocketHelper("ws://192.168.100.64:8181", function (cmd)
{
    switch (cmd.command)
    {
        case commands.gameover:

            // GAME Over
            break;

        case commands.start:
            
            alert("Welcome {0}. Are you ready?".format(cmd.player));
            break;

        default: throw new Error("Invalid Command on socket server.");

    }
});

Enviando mensajes:

socket.SendCommand(
{
    command: commands.start,
    player: 'Pepe el loco',
    device: 1,
    language: 'es'
});

y con esto ya tenemos una comunicación simple de browser a browser.

Más adelante veremos otro ejemplo en el que vamos a darle más responsabilidad al SocketServer enviando comandos recibidos desde una Kinect a clientes Web y ya de paso, convertiremos nuestro WebSocket en un servicio Windows.

Salu2

Navigator para WP7 en MVVM

Otro tema que estaba pendiente…

Cuando empecé a estudiar y testear cosas de WP7 con MVVM, una de los detalles que más me molestaban era tener que navegar entre páginas usando el code behind.

Es verdad que desde el ViewModel puedes tener acceso al NavigationService, pero esto sería una muy mala práctica de cara a los test unitarios. Por otra parte, desde dónde puedo capturar los parámetros pasados a una vista es siempre el método OnNavigatedTo que tenemos en el Code Behind.

Una tarde escuchando una charla de Josue sobre WP7, comentó que se encontraba desarrollando una aplicación llamada WPControla. Soy de los que piensa que una de las mejores maneras de tomar buenas prácticas en los desarrollos es mirar mucho código, cualquiera, no importa de quien sea porque siempre te ayudan a comparar y sacar conclusiones sobre lo que se debe o no hacer. 

En la propia charla le pregunté a Josue si podríamos descargarnos el código de la aplicación y como siempre, nos dio acceso al repositorio. Winking smile

Mirando el código de esta aplicación descubrí algo que me llamó mucho la atención, dentro del namespace WPControla.Client.Services había una clase llamada NavigationService. Me imaginé que esta clase, al implementar una interfaz sería una solución a lo que tanto me había molestado hasta el momento, poder navegar entre Views desde el ViewModel sin afectar los test.

Me costó entender cómo funcionaba porque en el repo no está toda la funcionalidad aún implementada, así que le pregunté directamente a Josue si esto era lo que me imaginaba y cómo había pensado en resolver esto, su respuesta no se hizo esperar. Gracias Josue! Smile

Con permiso del Master, vamos a intentar explicar la solución que implementa  WPControla.

Todo parte de una clase llamada NavController en la cual se empieza definiendo un singleton para el acceso a una única instancia. También contamos con un Dictionary que nos permite registrar y referenciar las vistas mediante “alias”.

registeredViews.Add("Start", new Uri(@"/MainPage.xaml", UriKind.Relative));

En mi caso, cambié el Dictionary utilizado:

static Dictionary<String, Uri> registeredViews = new Dictionary<String, Uri>();

por:

private static readonly Dictionary<Pages, Uri> _registeredViews = new Dictionary<Pages, Uri>();

Pages es un enumerado, esto no implica ninguna mejora a la solución planteada por Josue, más bien es un gusto personal, no me gusta trabajar con string porque soy muy despistado Sad smile y siempre los escribo mal, así que me ahorro errores de ejecución usando enumerados.

La clase define  tres sobrecargas sobre el método NavigateTo. Una sobrecarga nos permite navegar a una vista sin pasar parámetros, en la segunda, podemos incorporar parámetros pasados por QueryString y en la tercera nos vamos a detener:

public void NavigateTo(String navigationTarget, Action<NavigationEventArgs> onNavigated)

Esta sobrecarga incluye un Action<NavigationEventArgs> como parámetro, el objetivo es poder tomar una acción en el momento en que se navegue de una vista a otra. Internamente la clase navController captura el evento Navigated de PhoneApplicationFrame y cuando este ocurre, ejecuta nuestra acción.

/// <summary>
/// Este evento se lanza cuando hemos navegado a una página.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void root_Navigated(object sender, NavigationEventArgs e)
{
    if (NavigationMethod != null)
    {
        NavigationMethod(e);
        NavigationMethod = null;
    }
}

Este método de la forma que está escrito, no nos permite capturar el Navigated cuando el NavigationMode es Back, o sea, cuando vamos de regreso. Para solucionarlo solo necesitamos eliminar la línea de código que asigna null al NavigationMethod y no olvidar desasignar el evento cuando regresemos, porque de lo contrario navegando hacia atrás y hacia adelante multiplicará la cantidad de veces que se ejecuta nuestra acción.

void RootNavigated(object sender, NavigationEventArgs e)
{
    if (_navigationMethod == null) return;

    _navigationMethod(e);

    if (e.NavigationMode != NavigationMode.Back) return;
    var rootFrame = (PhoneApplicationFrame)Application.Current.RootVisual;
        
    rootFrame.Navigated -= RootNavigated;
}

Otra particularidad de esta sobrecarga es que mediante el parámetro NavigationEventArgs tenemos acceso a la View que estamos navegando mediante la propiedad Content, a su vez, mediante la View tenemos acceso al DataContext que en una arquitectura MVVM sería el ViewModel. Esta estructura pudiera ser utilizada para inicializar objetos complejos cuando navegamos de una vista a otra (luego veremos un ejemplo).

Ya que estamos creando métodos de navegación, adicioné a esta clase un método que nos permita hacer Back por código.

public void NavigateToBack()
{
    var rootFrame = Application.Current.RootVisual as PhoneApplicationFrame;
    if (rootFrame == null || !rootFrame.CanGoBack) return;

    rootFrame.GoBack();
}

La magia para que todo esto se integre con nuestros ViewModels llega ahora:

Definimos una interfaz con los distintos métodos para la navegación que necesitamos en nuestra aplicación, hacemos que un servicio implemente dicha interfaz y lo usamos en el constructor de los distintos ViewModels.

Un servicio de navegación que utilice NavController quedaría como el siguiente:

public interface INavigatorService
{
    void GotoMvvmView1();
    void GotoMvvmView1(DataItem param);

    void GoBack();
}

public class NavigatorService : INavigatorService
{
    public void GotoMvvmView1()
    {
        NavController.Current.NavigateTo(NavController.Pages.MvvmView1);
    }

    public void GotoMvvmView1(DataItem param)
    {
        NavController.Current.NavigateTo(NavController.Pages.MvvmView1, 
            args =>
            {
                if (args.NavigationMode != NavigationMode.New) return;

                var view1Model = ((FrameworkElement) (args.Content)).DataContext as View1ViewModel;
                if (view1Model != null) view1Model.Initialize(param);
            });
    }

    public void GoBack()
    {
        NavController.Current.NavigateToBack();
    }
}

Observen como estamos ejecutando una acción en el momento en que llegamos a la vista a la que deseamos navegar. Esta acción accede al ViewModel e inicializa parámetros necesarios con los datos que se pasan al método GotoMvvmView1.

A mi este mecanismo no me gusta  (cuestión personal), no sé si será buena o mala práctica, pero me cuesta tener que acceder a métodos del ViewModel desde este punto.

Para solucionar este problema he incorporado a la clase NavController un Dicctionary para pasar datos entre vistas.

/// <summary>
/// Navigation Parameters 
/// </summary>
public static IDictionary<string, object> Parameters { get; set; }

Como NavNavigator es independiente de nuestros ViewModels mediante una interfaz, tenemos que adicionar a la misma la utilización del Dictionary. La interfaz vista anteriormente ahora nos quedaría así:

public interface INavigatorService
{
    IDictionary<string, object> Parameters { get; set; }

    void GotoMvvmView1();
    void GotoMvvmView1(DataItem param);

    void GoBack();
}

y su implementación sería…

public class NavigatorService : INavigatorService
{
    public IDictionary<string, object> Parameters
    {
        get { return NavController.Parameters; }
        set { NavController.Parameters = value; }
    }

    public void GotoMvvmView1()
    {
        NavController.Current.NavigateTo(NavController.Pages.MvvmView1);
    }

    public void GotoMvvmView1(DataItem param)
    {
        NavController.Current.NavigateTo(NavController.Pages.MvvmView1, 
            args =>
            {
                if (args.NavigationMode == NavigationMode.Back) return;

                NavController.Parameters = new Dictionary<string, object> { { "item", param} };
            });
    }

    public void GoBack()
    {
        NavController.Current.NavigateToBack();
    }
}

Después de tener esto solo nos queda pasar el servicio de navegación en el constructor de nuestros ViewModels y acceder a los distintos métodos para navegar.

/// <summary>
/// Initializes a new instance of the MainViewModel class.
/// </summary>
public MainViewModel(IDataService dataService, INavigatorService navigator)
private void GotoView1Command()
{
    _navigator.GotoMvvmView1(_item);
}

Quizás pienses que a esta altura, cuando ya WP7 solo tendrá una próxima actualización y las cosas cambiarán de cara a WP8 y a la nueva interfaz de W8 (antes Metro), ya no tienen mucho sentido. Puedes echarle una ojeada a este post sobre W8 del propio Josue y seguramente habrá cosas que te resulten familiar. Winking smile

Salu2

Código del ejemplo