Presentación para el Tercer Simposio Latinoamericano de Sharepoint

by Misael Monterroca 2. June 2010 17:42

Les comparto la presentación que utilizare dentro del Tercer Simposio Latinoamericano de SharePoint. Cualquier duda no duden en poner un comentario en el blog.

Tags:

SharePoint | SharePoint 2010 | Visual Studio | Visual Studio 2010

Tercer Simposio Latinoamericano de SharePoint en México

by Misael Monterroca 24. May 2010 04:16

Hola!

Los invito al Tercer Simposio Latinoamericano de SharePoint en México, este año no tendrá costo ya que está patrocinado por Microsoft, será un evento 100% enfocado al desarrollo sobre SharePoint 2010 y yo estaré participando en la primera platica, les dejo la agenda y la liga para el registro.

Saludos!

Agenda por la mañana (Desarrollo)

1. Desarrollo en Visual Studio 2010: Conozca las ventajas y beneficios del desarrollo para SharePoint 2010
2. Silverlight 4 y SharePoint 2010: Como hacer mis sitios web más atractivos a mis usuarios
3. Power Pivot y generación/presentación de BI
4. Office Business Applications (OBA) 2010: Conozca cómo puede extender las funcionalidades de Office y generar valor en su integración con aplicaciones corporativas y de colaboración

Agenda por la tarde (IT Pros, TDM, BDM)

1. Ventajas y beneficios de SharePoint 2010: Beneficios de las nueva versione de SharePoint 2010
2. Migrando a SharePoint 2010: Cuales son los caminos recomendados para migrar a SharePoint 2010

3. Top 10 tips to successfully deploy SharePoint 2010/business value

4. Productividad en la Nube, Cloud Services, BPOS

Liga para registrarse -> https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032452786&Culture=es-MX

Tags:

Obtener el NameSpace y los tipos de un ensamblado

by Misael Monterroca 21. May 2010 14:13

Para un documento de arquitectura que estoy elaborando, me vi en la necesidad de obtener los namespaces y los tipos de un determinado ensamblado, el siguiente código les permitirá obtenerlos utilizando reflection y escribirlos en un archivo de texto.

La aplicación leerá los ensamblados que se encuentren dentro de un directorio dejando un archivo llamado datos.txt que tendrá un contenido similar al siguiente:

Para el ensamblado Contoso.SN.Framework
NAMESPACES

Contoso.SN.Framework
Contoso.SN.Framework.Exceptions
Contoso.Sacip.Framework.Infopath
……..

CLASES

ConfigurationException
ConfigurationSettings
……

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
            {
                DirectoryInfo directory = new DirectoryInfo(@"C:\dlls");
                var dls = directory.GetFiles("*.dll");

                if (File.Exists("datos.txt"))
                    File.Delete("datos.txt");
            
            using (StreamWriter writer = File.CreateText("datos.txt"))
                {
                    foreach (var item in dls)
                    {

                        var assembly = Assembly.LoadFrom(item.FullName);

                        Console.WriteLine("Para el ensamblado " + assembly.GetName().Name);
                        writer.WriteLine("Para el ensamblado " + assembly.GetName().Name);
                        writer.WriteLine("NAMESPACES ");
                        writer.WriteLine();

                        var namespaces = assembly.GetTypes().Select(T => T.Namespace).Distinct();
                        foreach (var type in namespaces)
                        {
                            Console.WriteLine(type);
                            writer.WriteLine(type);
                        }

                        writer.WriteLine();
                        writer.WriteLine();

                        writer.WriteLine("Tipos ");
                        var types = assembly.GetTypes().OrderBy(T => T.Name);
                        foreach (var type in types)
                        {
                            if(!type.IsNested)
                                writer.WriteLine(type.Name);
                        }

                        writer.WriteLine();
                        writer.WriteLine();
                    }
                }

                Console.ReadKey();
            }
    }
}

Tags:

Reunión de la Comunidad .NET de la Ciudad de México del mes de noviembre

by Misael Monterroca 26. November 2009 17:28

El día de hoy será la reunión de comunidad de la cd de México, las platicas estaran muy interesantes y tambien se transmitiran por live meeting para quienes no puedan asistir fisicamente. Mas información de las platicas ->  http://www.superneurona.com/

 Para conectarse por livemeeting sigan las siguientes instrucciones:

 

Misael Monterroca has invited you to attend an online meeting using Live Meeting.
Join the meeting.
Audio Information
Computer Audio
To use computer audio, you need speakers and microphone, or a headset.
First Time Users:
To save time before the meeting, check your system to make sure it is ready to use Microsoft Office Live Meeting.
Troubleshooting
Unable to join the meeting? Follow these steps:  1.      Copy this address and paste it into your web browser:
https://www.livemeeting.com/cc/mvp_no_voip/join 2.      Copy and paste the required information:
Meeting ID: GN249Q
Entry Code: FJZ5!Dx[F
Location: https://www.livemeeting.com/cc/mvp_no_voip

 

Tags:

Comunidades

Adios SourceSafe Hola Team Foundation Basic

by Misael Monterroca 15. November 2009 09:41

De todos es conocido que SourceSafe es una muy buena solución para realizar el manejo de versiones principalmente de nuestro código. VSS lo recuerdo desde que utilizaba Visual Basic 6, y al día de hoy solo ha sufrido pequeños cambios para soportar el ide de Visual Studio 2002, 2003 y 2005 y claro, 2008 pero internamente seguia siendo el mismo motor.

 Como parte de la familia de Visual Studio se lanzo hace unos años la suite de Team Foundation Server, que entre algunas de sus caracteristicas trae consigo un control de versiones pero como repositorio de información es MS SQL (Source Safe, son archivos de texto), la utilización de sql server trajo consigo muchos beneficios entre ellos, Garantizar la atomicidad de la información que es almacenada, algo que sourcesafe no garantiza y razón por la cual constantemente hay que hacer analisis de sus indices para evitar corrupciones de información.

Team Foundation Server como les comentaba, NO solo es un producto para realizar el control de versiones incluye bastantes caracteristicas como:

  1. Build Server
  2. Manejo de Work Items (En pocas palabras, tareas asignables a los diferentes roles de un equipo de desarrollo)
  3. Integración con project (Para la administración de algunos tipos de Work Items)
  4. Reportes (Para medir el desempeño del equipo de trabajo)
  5. Un largo y gran etc

Estas caracteristicas hacen que sea un producto que no esta destinado a un equipo pequeño de desarrollo (anque de ninguna manera está excluido) en donde el unico requisito sea llevar el control de código fuente.

La buena noticia es que con la versión 2010 Microsoft saco un producto llamado Team Foundation Server Basic (TFS Basic), en realidad no es un producto, es parte de Team Foundation Server pero es un rol más que se podra configurar en donde se podran seleccionar las siguientes caracteristicas

  • Control de código fuente (ahora si, adios Source Safe)
  • Manejo de Work Items (sin integración con project, y mucho menos con sharepoint)
  • Build Server

En porteriores post, les estare explicando un poco más el detalle de todas estas caracteristicas.

Tags: , ,

TFS Basic | VS2010 | TFS

Lazy initialization en .NET 4

by Misael Monterroca 26. October 2009 06:27

La inicialización del tipo Lazy (la traducción seria perezosa pero se refiere al hecho de crear un objeto hasta el momento de realmente utilizarlo aún y cuando el objeto sea instanciado en líneas anteriores) permite optimizar la manera en que creamos nuestros objetos.  En .Net. C# 4.0 se introduce la clase Lazy<T> que permite inicializar los objetos hasta que realmente los vayamos a utilizar, veamos el siguiente ejemplo:

class Program
{
    static void Main(string[] args)
    {
        Lazy<Prueba> f = new Lazy<Prueba>( );
        Console.WriteLine("Prueba es definida");
        if (!f.IsValueCreated) Console.WriteLine("Prueba aún no ha sido inicializada");
        Console.WriteLine("Prueba::ID=" + (f.Value as Prueba).ID);
        
        if (f.IsValueCreated) Console.WriteLine("Prueba ahora si está inicializada");
        Console.Read();
    }
} 

public class Prueba
{
    public int ID { get; set; }
    
    public Prueba()
    {
        Console.WriteLine("Prueba:: El constructor es llamado");
        ID = 1;
    }
}

La ejecución obtendría el siguiente resultado:

Prueba es definida
Prueba aún no ha sido inicializada
Prueba:: El constructor es llamado
Prueba::ID=1
Prueba ahora si está inicializada

Como podemos ver el objeto Prueba se crea sólo cuando f.Value es accesado.

Tags: ,

C# | C# 4.0

Code Contracts

by Misael Monterroca 6. October 2009 06:48

Code Contracts permiten especificar el comportamiento de un algoritmo de forma explícita la adhesión a un contrato bien claramente definido. Por lo general, estos contratos son en forma de pre y post condiciones. Además, uno también puede especificar los contratos de un tipo de comportamiento en forma de un tipo invariante . Por ahora no tienes que preocuparte acerca de cómo estos contratos se pueden definir (discutiremos esto más adelante), sin embargo, es importante entender algunos de los beneficios de utilizar contratos de código, estos incluyen:

  • Proporcionar una descripción del comportamiento de alto nivel de un algoritmo;
  • Fuera a los programadores a ser explícitos sobre el comportamiento de sus procedimientos
  • Ayudar a detectar fallos tempranos.

.

Spec #

Spec # es un Proyecto de investigación de Microsoft que extiende el lenguaje C # 2 .0  de modo que puede definir fácilmente los contratos de código. Además, Spec # también proporciona controles en tiempo de compilación para verificar ciertas reglas definidas al compilar, por ejemplo que un objeto no nulo se pasa a un algoritmo. En esta sección veremos algunas de las características que el lenguaje Spec# introduce comenzando por las precondiciones.

Pre-condiciones

Las Pre-condiciones definen las propiedades que requiere un algoritmo funcionar adecuadamente; estas propiedades están definidas por el programador del algoritmo.

Para nuestro primer ejemplo vamos a ver cómo podemos definir una restricción no nulo para un argumento de un método:

class MyType
{
// ...
void MyAlgorithm(Parametro! parametro)
{
// ...
}
}

En el código anterior simplemente se a  añadido un  “!después del tipo de argumento para definir una restricción de no pasar parametros null, esta restricción se comprueba en tiempo de compilación por el compilador Spec#.

Tags:

Named and Optional Parameters

by Misael Monterroca 29. September 2009 06:15

C # 4.0 ha añadido dos nuevas características en relación con los parámetros que deberían contribuir a mejorar la productividad del desarrollador.  Parametros Opcionales y Parametros por nombre permitirá  nuevas maneras de resolver viejos problemas.

Parámetros opcionales

En el pasado, cuando queríamos crear métodos con un número variable de parámetros debiamos utilizar métodos sobrecargados. La sobrecarga es el proceso de creación de métodos con el mismo nombre pero de diferentes parámetros. Por ejemplo, digamos que tenemos un método denominado GetRandomNumber que cuenta con tres firmas de métodos diferentes:

 

01    static void Main(string[] args)
02    private static Random random = new Random();      
03     
04    public static int GetRandomNumber(int max)
05    {
06        return random.Next(max);
07    }
08     
09    public static int GetRandomNumber(int min, int max)
10    {
11        return random.Next(min, max);
12    }
13     
14    public static int GetRandomNumber()
15    {
16        return random.Next();
17    }

Con C # 4, ahora podemos consolidar estas en un método con parámetros opcionales. Los parámetros opcionales le permiten declarar e inicializar una variable dentro de la firma del método. Cualquier parámetro que tiene un valor por defecto asignado a ella puede ser excluido al invocar el método. Por lo tanto podemos consolidar nuestro código anterior:

01    private static Random random = new Random();
02     
03    public static int GetRandomNumber(int min = -1, int max = -1)
04    {           
05        if (min == -1 && max != -1)
06            return random.Next(max);
07        else if (min != -1 && max != -1)
08            return random.Next(min, max);
09        else
10            return random.Next();
11    }

 

El escenario clásico para el uso de parámetros opcionales surge cuando están interactuando con interfaces COM como la Automatización de Microsoft Office API. Si usted ha trabajado con las APIs de Office antes, entonces estoy seguro de que usted está familiarizado con el Type.Missing. Antes de C # 4.0, tendríamos que utilizar el siguiente código para dar formato a un rango de celdas con Excel:

1    var excel = new Microsoft.Office.Interop.Excel.Application();
2    excel.Workbooks.Add();
3    excel.Visible = true;
4     
5    var format = Microsoft.Office.Interop.Excel.XlRangeAutoFormat.xlRangeAutoFormatClassic1;
6     
7    excel.get_Range("B10", "B40").AutoFormat(format,
8       //y !6! Type.Missing
9       Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);

Este código parece un desperdicio debido al hecho de que tenemos que llenar en seis de los siete parámetros con Type.Missing. En C # 4.0, la llamada al método  AutoFormat se simplifica. Básicamente, se pueden prevenir todos los parámetros repetitivos como Type.Missing y solo especificar el primer parámetro, como en siguiente ejemplo:

excel.get_Range("B10", "B40").AutoFormat( format );

Parámetros con nombre

Named Parameters es la otra nueva característica en C # 4.0. Los parámetros con nombre son muy útiles en situaciones en las que es fácil olvidar el orden en el que los parámetros están especificados. Volviendo a mi primer ejemplo que tenía un generador de números aleatorios que tiene un valor mínimo y un valor máximo. Si por alguna razón se invirtieran el valor de los parámetros obviamente el resultado seria equivocados. Sin embargo, con Named Parameters podemos seleccionar los parámetros especificando el nombre del parámetro y el valor. Aquí está un ejemplo:

 

Console.WriteLine( GetRandomNumber( max : 100, min : 1 ) );

Tags: ,

C# | C# 4.0

Covariance and Contravariance

by Misael Monterroca 9. September 2009 19:58

Una de las nuevas características de C# 4.0 es la covarianza y contravarianza en los parámetros de tipo que ahora es soportado por los delegados genéricos y las interfaces genéricas. En primer lugar vamos a ver ¿qué significan estas palabras?

En general, si tenemos alguna entidad (interfaz o delegado) que es genérico en el tipo T podriamos suponer que tengamos una definición del tipo Entidad<T>, suponiendo que tengamos  dos entidades concretas Entidad<A> y Entidad<B> donde B hereda de A, en este caso  no hay relaciones de herencia entre Entidad<A> y Entidad<B>. Covarianza (y contravarianza) añade precisamente este tipo de relaciones:

Covariance y Contravariance agrega algunas restricciones a la interfaz correspondiente o delegado. Covarianza se admite sólo en algunos casos, y en algunos otros casos se admite la contravarianza. Vamos a detallar cuáles son esas restricciones.

Restrincciones

La primera restricción es que los temas de covarianza y contravarianza están disponibles únicamente a los delegados e interfaces.

La segunda es que el tipo genérico utilizado para la covarianza y  contravarianza debe ser un tipo de referencia. Sin embargo el tipo genérico no se limita a ser un tipo de referencia.El tipo de valor se puede utilizar también, pero no habrá relaciones de herencia para ello.

 

interface ICovariant<out T> { }

interface IInterface { }

struct MiEstructura : IInterface { } // tipo por valor, hereda de IInterface

class CovariantS : ICovariant<MiEstructura> { }

static void Main(string[] args)
{
    ICovariant<MiEstructura> covariantS = new CovariantS();
    ICovariant<IInterface> covariantI = covariantS; // <-- Aqui daria un error de compilación
}

Y la tercera (y más importante) es lo siguiente:  El tipo que se va a utilizar para la covarianza sólo se puede utilizar como tipo para devolver valores en la interfaz correspondiente de delegado. Y el tipo que se va a utilizar para contravarianza sólo se puede utilizar como tipo de parámetros de entrada en la interfaz correspondiente de delegado. (Aquí y en todo el artículo me refiero a ese tipo utilizando para el método setter es lo mismo que usar como parámetro de entrada, y usarlo para el método getter es lo mismo que usar como valor de retorno.) Tanto covariantes y contravariantes tipos. Asimismo, no se puede utilizar como tipos ref (o out).

 

delegate T /* Permitido */ CovariantProcessor<out T>(
    T value /* No Permitido */, ref T reference /* not allowed */);

delegate T /* No Permitido */ ContravariantProcessor<in T>(
    T value /* Permitido */, ref T reference /* No Permitido */);

interface ICovariant<out T>
{
    T Generate(); // permitido
    void Use(T value); // no permitido
    void Change(ref T reference); // no permitido

    T Value
    {
        get; // permitido
        set; // no permitido
    }
}

interface IContravariant<in T>
{
    T Generate(); // no permitido
    void Use(T value); // permitiddo
    void Change(ref T reference); // no permitido

    T Value
    {
        get; // no permitido
        set; // permitido
    }
}

Sin esas restricciones vamos a llegar a una gran cantidad de conflictos. Es mejor que hagamos un ejemplo.

Crearemos dos clases de mamiferos, Perro y Gato

 

class Mamifero { }

class Perro : Mamifero { }

class Gato : Mamifero { }
interface ICovariantWrapper<out T>
{
    T Value 
    { 
        get; 
        set; // no permitido
    }
}

class Wrapper<T> : ICovariantWrapper<T>
{
    T Value { get; set; }
}

static void Main(string[] args)
{
    ICovariantWrapper<Perro> wrappedDog = new Wrapper<Perro>();

    // creando un objeto de mamiferos del mismo tipo del perro
    ICovariantWrapper<Mamifero> wrappedMammal = wrappedDog;

    
    // poniendo el objeto gato dentro del objeto perro
    wrappedMammal.Value = new Gato(); 

    Perro dog = wrappedDog.Value; // el objeto en realidad ya es un gato
}

La única diferencia es que en primer lugar IContravariantWrapper<Mamifero> y luego se realizo un cast a IContravariantWrapper<Perro>. Después de esto el objeto Gatose puede asignar al objeto Perro.

Veamos unos ejemplos ya que la siempre teoría no siempre es suficiente.

Ejemplo Covarianza

Vamos a utilizar el interfaz ICreator<T> que es capaz de crear instancias de T diferentes fuentes. También vamos a utilizar dos clases: Entity y una subclase SerializableEntity.

public interface ICreator<T>
{
    T CreateDefault();

    T CreateFromXDocument(XDocument xDocument);

    T CreateFromStream(Stream stream);
}

public class Entity
{
    /* ... */
}

public class SerializableEntity : Entity
{
    /* ... */
}

Ahora imaginemos que tenemos la clase SerializableEntityCreator que implementa la interfaz ICreator de SerializableEntity. Y también imagina que tenemos la clase EntityManager que necesita una instancia de ICreator<Entity> que funcione correctamente.

 

public class SerializableEntityCreator : ICreator<SerializableEntity>
{
    /* ... */
}

public class EntityManager
{
    public EntityManager(ICreator<Entity> entityCreator)
    {
        /* ... */
    }
}

Vamos a ver ahora lo que tenemos. Por un lado tenemos SerializableEntityCreator que es capaz de crear instancias de SerializableEntity. también puede crear instancias de Entity porque cada SerializableEntity es una Entity también. Por otro lado tenemos EntityManager que necesita algo que se puede crear instancias de Entity. Parece que SerializableEntityCreator va a coincidir con EntityManager pero sin covarianza no es cierto y el siguiente código no compilará:

 

ICreator<SerializableEntity> entityCreator 
    = new SerializableEntityCreator();
EntityManager manager = new EntityManager(entityCreator); // error

Para resolver este problema en C # 2.0/3.0 tenemos que aplicar tanto ICreator<Entity> y ICreator <SerializableEntity> en SerializableEntityCreator. Pero en C # 4.0 esto puede hacerse al sólo se declarar como covariant a la interfaz

 

public interface ICreator<out T>
{
    /* ... */
}

Ahora ICreator<T> es covariante por T. Eso significa que SerializableEntityCreator no sólo es ICreator<SerilizableEntity>, pero es una ICreator<Entity> también.

 

ICreator<SerializableEntity> entityCreator 
    = new SerializableEntityCreator();
EntityManager manager = new EntityManager(entityCreator); // ya no dará error y compilara

Tags:

Clases Parciales

by Misael Monterroca 18. August 2009 13:57

En general, las clases se definen en un mismo archivo fuente (Clase1.cs, Clase2.cs etc) . A veces, esto puede conducir a dificultades, un ejemplo es una clase que está parcialmente generado por un generador de código, y parcialmente modificada y mantenida por el desarrollador.

Este es un escenario muy común, WinForms y diseñadores de formularios Web Forms tiene este problema, haciendo que estas clases sean vulnerables a la modificación accidental de código fuente que no está destinado a ser modificada por el desarrollador. Para resolver este problema, el código generado por el diseñador WinForm está escondido en una región y generalmente nunca es modificada por ningún desarrollador.

C # presenta una característica que puede resolver estos problemas: las clases parciales. Estas son clases que se definen en más de un archivo de origen. De esta manera, parte de una clase parcial podría ser gestionada por el generador de código y una segunda parte de la clase podría ser gestionada por el desarrollador. Cuando el código se compila, el compilador de C # realiza lo que se puede describir como una  fusión que combina todas las partes en una clase.

He aquí un ejemplo de código. En primer lugar, podría haber una parte de una clase definida en un archivo de origen:

 

public partial class Class1
{
   public string Test()
   {
      return "Prueba";
   }
}

Entonces, podría haber una segunda fuente de archivos con la siguiente definición de clase:

 

public partial class Class1
{
   public string SomethingElse()
   {
      return "Alguna otra funcionalidad más";
   }
}

La parte importante es la definición de la clase es la palabra clave partial, lo que hace que el nombre duplicado de la clase sea válido, además instruye al compilador a fusionar las dos partes.

Por supuesto, esta fusión puede ser útil para un número de diferentes aplicaciones prácticas, los generadores de código es uno de ellos. Además, las clases parciales se pueden utilizar crear grandes clases en pedacitos más pequeños, que puede ser muy útil en escenarios de desarrollo ya que puede ser una característica útil cuando se trata de agregar funcionalidad a una clase de depuración ya que una de las partes podría tener toda la funcionalidad de depuración, y en otra, el código esperado, una vez que el producto este listo, la clase que contenga el código de depuración podría ser removido sin afectar el código esperado.

Tags:

C# | c

MVP