InternalsVisibleTo

Hoy he descubierto el atributo InternalsVisibleTo, este atributo esta definido en el namespace System.Runtime.CompilerServices. Nos permite utilizar metodos y tipos internos de un assembly.

si yo tengo un assembly que implementa la siguiente clase

internal class MiInternalClass
{
public void Metodo1() {...}
internal void InternalMetodo() {...}
}

Si yo en mi proyecto, al cual le he añadido la referencia del assembly donde se encuentra esa clase, le añado al fichero AssemblyInfo.cs la linea

[assembly: InternalsVisibleTo(«NombreAssembly»)]

En mi proyecto podre utilizar MiInternalClass y llamar a los emtodos publicos o internos.

Hay que reseñar que utilizando esta tecnica violamos la encapsulación de los internals que declaramos en nuestros assemblies, pero puede haber casos que nos venga bien esta tecnica como por ejemplo si tenemos un assemblie ya creado y lo queremos dividir en varios assemblies.

Creando nuestros validadores en Validation Application Block

Muchas veces nos puede pasar que necesitemos validadores que no esten implemntados en Validation Application Block. Esto no es problema ya que la arquitectura de VAB nos permite crear nuestros propios validadores. Imaginemos que queremos crear un validador para e-mails que comprobara que el string contiene el caracter @.

Para ello debemos crear una clase denominada EmailValidatorAttribute que herede de ValidatorAttribute y sobreescribir el metodo CreateValidator.

 

public sealed class EmailValidatorAttribute : ValidatorAttribute
{
	public override IValidator CreateValidator()
	{
		return new EmailValidator(this.GetMessageTemplate());
	}
} 

 

Ahora creamos la clase EmailValidator que debe heredar de ValidatorBase y sobreescribir los metodos DoValidate, en el que realizaremos la validación, y el metodo GetDefaultMessageTemplate, en el que introduciremos el mesaje por defecto.

 

       public class EmailValidator : ValidatorBase
    {
        public EmailValidator()
            : this(null)
        { } 

        public EmailValidator(string messageTemplate)
            : base(messageTemplate)
        { } 

        protected override void DoValidate(object target, ValidationResults validationResults)
        {
            try
            {
                string converted = (string)target;
                if (!converted.Contains("@"))
                {
                    this.AddResult(validationResults, new ValidationResult(this.MessageTemplate));
                }
            }
            catch
            {
                this.AddResult(validationResults, new ValidationResult(this.MessageTemplate));
            }
        } 

        protected override string GetDefaultMessageTemplate()
        {
            return "No es un email valido, no contiene el caracter @";
        }
    }

De esta manera tan sencilla creamos nuesteos propios validadores

Validation Application Block Enterprise Library 3.0

Siguiendo con la nueva versión de Enterprise Library despues de mirar las mejoras de configuración, me he puesto a mirar Validation Application Block y me ha vuelto a sorprender gratamente. Primero porque utiliza atributos para validar y segundo proque se utiliza de forma natural y sencilla.

Validation Application Block viene con un numero de  ValidatorAttributes  que podemos utilizar para decorar nuestras clases. El número de ValidatorAttributes es amplio aunque podemos incluso crear nuestros porpios validadores.

Un ejemplo sencillo de su utilización seria el siguiente trozo de codigo, donde creo una clase cliente con tres atributos a los cuales les indico mediante ValidatorAttributes, cuales quiero que sean sus validaciones.

 

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Practices.EnterpriseLibrary.Validation.Validators;

namespace Prueba1
{
    public class Cliente
    {
        private string _nombre;

        [NotNullValidator]
        [StringLengthValidator(1, 200)]
        public string Nombre
        {
            get { return _nombre; }
            set { _nombre = value; }
        }
        private string _telefono;

        [RegexValidator(@"(d{3}) d{3}-d{4}")]
        public string Telefono
        {
            get { return _telefono; }
            set { _telefono = value; }
        }

        private int _edad;
        [Int32RangeValidator(23,50)]
        public int Edad
        {
            get { return _edad; }
            set { _edad = value; }
        }
	
	
    }
}
 

Como podeis ver es una forma muy sencilla. Ahora como valido una instancia de Cliente?

Tan sencillo como utilizar Validation Facade Class

	
ValidationResults results = Validation.Validate(cliente);

if (!results.IsValid)
{
        foreach (ValidationResult result in results)
        Console.WriteLine(string.Format("Key: {0},Message: {1}", result.Key.ToString(), result.Message));

    Console.ReadLine();
}

 

Espero que os haya gustado

Enterprise Library 3.0 Editor Configuración Integrado en Visual Studio

Despues de ver por todas partes el anuncio del lanzamiento de la CTP de Enero de Enterprise Librery 3.0, me he decidido a probarlo y lo primero ya me ha encantando.


El configurador de Enterprise Libarry integrado en Visual Studio. Ahora ya no tenemos que pasar de la aplicación de Visual Studio al configurador de Enterprise con la tecla TAB si no que viene totalmente integrado.


Con el boton derecho del ratón en el fichero de configuración de nuestro proyecto, ya nos aparece directamente la entrada en el menu para editarlo con Enterprise


 



Y al seleccionarlo, vemos que nos crea una nueva ventana en el editor de Visual Studio



Ademas como podeis ver tenemos la entrada de Application Settings, donde podemos visualizar nuestras claves de configuración y introducir los valores



Una nueva funcionalidad del editor y que se echaba en falta en la versión 2.0 es la encriptación de las strings de conexión.


Seleccionando Data Access Application Block y pulsando F4 nos sale la ventana de propiedades donde vemos la entrada Protection provider



Donde podemos seleccionar



De manera que al editar el app.config veriamos


 

<?xml version=»1.0″ encoding=»utf-8″?>
<configuration>
<configSections>
<section name=«dataConfiguration» type=«Microsoft.Practices.EnterpriseLibrary.Data.
Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=2.9.9.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a» />
</configSections>
<dataConfiguration configProtectionProvider=«DataProtectionConfigurationProvider»>
<EncryptedData>
<CipherData>
<CipherValue>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAFRI++2/+LU6+s/kHbY8U7wQAAAACAAAAAAADZgAAqAAAABAAAAAE
0kMcKCdL/GgbY0GUInLSAAAAAASAAACgAAAAEAAAAOs7Nx6Y7FvhtZfUBlGUOYAwAAAA1uvuFKsJxR4udMV2SqVudh+yfAoii44CREUT9
maE4JZsFsJvbFrM5rFrGCJl0lMxFAAAAByz2xJv8qMbr+aEHzUrfrL8uRWI</CipherValue>
</CipherData>
</EncryptedData>
</dataConfiguration>
<connectionStrings configProtectionProvider=«DataProtectionConfigurationProvider»>
<EncryptedData>
<CipherData>
<CipherValue>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAFRI++2/+LU6+s/kHbY8U7wQAAAACAAAAAAADZgAAqAAAABAAAAA3JXr
7KDE48YY+tlMOVQmuAAAAAASAAACgAAAAEAAAAKXRPm1DaFWoBhHWGjqjBligAQAA8YPbToCERRAhTmDci9RGH0lokQqqDRvs7t+FRdxSag
dWw2TEjG0MpCQI8ZaEcllRZhma0PBDZf1VJb+RXHDC6xTGKErLZmqkfBuAYAg9PSL12TKiEn3TXFQWa8Syq8qdeHkaKMrFJIoBQ0UizOWq
6BuY59I1GoGh7ZotzHAgH9ajKiOzrnp0gpPyLbrwzbNtQ8xLsPCoSS7lrMk2oA222z0QAdNaUK5HYpuqaPpfhFQhluB1YvNfxdoXDMWWNL
5OrQXO3CANVuXIRztwNuY3XGf2l/0fIVjfp8KzUeQVG/lge3auE0xQYUVXEfCAW48BpAfjag0e+tKbpXQzniOalqRyOriFDHEc/+tkBJavp
6NcwcEadtaLtXSF5q9MXBIEUVzvTeldLiHahErRcSUxd8GNCFZBgYtpZ+auEEWeBBF+ycCgT2Oz/+zeZmaSYthLD06PuBAwDq+2NXOLT
oYFuXAzxQjybbwfMXWdZZctFDgV5RYy6a1BxkgbSdya/NHtHBVJqd87Sr+PRWfHzLNiulm7MyMToq/TMLqswGgOJp0UAAAAmwo8Nr+HEm7
5avdrUiy034w6D4U=</CipherValue>
</CipherData>
</EncryptedData>
</connectionStrings>
<appSettings>
<add key=«IP Servidor» value=«172.22.4.5» />
</appSettings>
</configuration>

 


La verdad 5 minutos trasteando con la nueva versión y ya se le ve mejoras sustanciales


Microsoft Office Add-in: Microsoft Outlook SMS Add-in

Hoy acabo de encontrar este Add-in que nos permite enviar mensajes SMS de texto mediante la mayor parte de teléfonos móviles GSM (Global System for Mobile Communications) conectados a un equipo en el que se utilice Microsoft Office Outlook 2007 o Microsoft Office Outlook 2003.

Aqui teneis la descarga

http://www.microsoft.com/downloads/details.aspx?displaylang=es&FamilyID=240080B4-986E-4AFB-AB21-3AF2BE63508B

Crear Custom Activities en WF

Como me ha tocado en el proyecto crear Custom Activities para WF voy a explicar como las he realizado.

Lo primero el usuario queria que las actividades quedasen reflejadas de un tamaño fijo y mas grande, que tuviese un color predeterminado por el, que el icono que habitualmente sale en las actividades no saliese y que el texto de la actividad saliese centrado. Esa fuerón las especificaciones que me dieron.

Para definir una Custom Activity en WF es bastante facil solo hay que derivar de la clase Activity y ya tenemos nuestra propia actividad. en esta clase podemos extenderla con las propiedades que necesitemos e interactuar con ella. Por ejemplo el siguiente código nos muestra una actividad

 

public class IdentificarLateralidadActivity : Activity
    {
		public string[] ActivityScreenControls;
        private int _idPaso = 32;

        public int IdPaso
        {
            get { return _idPaso; }
            set { _idPaso = value; }
        }
        
         protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
        {
            // Aqui se ejecuta la actividad, asi que tendriamos que lanzar un evento
            // que permita capturar que se ejecuta, y mostrar la pantalla que desemos
            return base.Execute(executionContext);
        }

        protected override void Initialize(IServiceProvider provider)
        {
            base.Initialize(provider);

            this.Name = "Identificar Lateralidad";
            this.Description = "";
        }
        protected override void InitializeProperties()
        {
            base.InitializeProperties();
        }

        protected override void OnActivityExecutionContextLoad(IServiceProvider provider)
        {
            base.OnActivityExecutionContextLoad(provider);
        }

        protected override void OnActivityExecutionContextUnload(IServiceProvider provider)
        {
            base.OnActivityExecutionContextUnload(provider);
        }

        protected override void OnClosed(IServiceProvider provider)
        {
            base.OnClosed(provider);
        }
    }

Pero con esto no cumplimos los requisitos del color, tamaño.. que nos puso el usuario. Para cumplir estos requisitos debo de implementar dos clases mas La primera debe derivar de la clase ActivityDesignerTheme y aqui especificaremso el color y algunas propiedades respecto al aspecto. En mi caso

 

 public class MyActivityDesignerTheme : ActivityDesignerTheme
    {

        public MyActivityDesignerTheme(WorkflowTheme theme)

            : base(theme)
        {

        }

        public override void Initialize()
        {

            base.Initialize();

            BorderColor = Color.FromArgb(251, 129, 6);
            BorderStyle = DashStyle.Solid;
            BackColorStart = Color.FromArgb(255, 128, 0);
            BackColorEnd = Color.FromArgb(255, 236, 217);
            BackgroundStyle = LinearGradientMode.ForwardDiagonal;
            ForeColor = Color.Black;

        }



    }

La segunda clase debe derivar de ActivityDesigner en la que especificaremos el diseño, como el tamaño.. Esta clase debe hacer referencia a MyActivityDesignerTheme a través de un atributo [ActivityDesignerTheme(typeof(MyActivityDesignerTheme))] de manera que indicamos que el diseñador de actividades utilize el tema creado por mi. El código del diseñador

 

[ActivityDesignerTheme(typeof(MyActivityDesignerTheme))]
    public class MyActivityDesigner : ActivityDesigner
    {
        //Damos un tamaño fijo a la actividad
        readonly static Size BaseSize = new Size(200, 50);


        //Quitamos el  icono
        protected override Rectangle ImageRectangle
        {

            get { return new Rectangle(new Point(0, 0), new Size(0, 0)); }

        }
        //Quitamos el texto
        protected override Rectangle TextRectangle
        {

            get { return new Rectangle(new Point(0, 0), new Size(0, 0)); }

        }

        protected override void Initialize(Activity activity)
        {

            base.Initialize(activity);

        }

        //Retonornamos el tamaño fijo
        protected override Size OnLayoutSize(ActivityDesignerLayoutEventArgs e)
        {

            base.OnLayoutSize(e);

            return BaseSize;

        }

        //sobreescribimos el metodo OnPaint indicando que dibjue un texto con el tamaño 
        //de la actividad y centrado
        protected override void OnPaint(ActivityDesignerPaintEventArgs e)
        {
            base.OnPaint(e);

            Graphics graphics = e.Graphics;

            MyActivityDesignerTheme compositeDesignerTheme = (MyActivityDesignerTheme)e.DesignerTheme;

            string text = this.Text;
            Rectangle textRectangle = this.Bounds;

            ActivityDesignerPaint.DrawText(graphics, compositeDesignerTheme.Font, text, textRectangle,
 StringAlignment.Center, e.AmbientTheme.TextQuality, compositeDesignerTheme.ForegroundBrush);
        }


    }

 Solo faltaria poner a la clase que he definido con la actividad el atributo

[DesignerAttribute(typeof(MyActivityDesigner), typeof(IDesigner))]

Indicando la clase de diseño que tiene que utilizar cuando dibuje esa actividad

De esta manera el resultado obtenido es

Servicios WCF y Vista

Intentando instalar un servicio WCF .svc en vista, hice los pasos de crear la aplicación en el IIS, dar permisos…), pero al llamarlo

HTTP 500   —  Handler svc-Integrated has a bad module «ManagedPipelineHandler» in its module list

El problema era que tenia que configurar la activacion de WCF HTTP, para ello en Activar o desactivar las caracteristicas de Windows, en Microsoft. Net FrameWork 3.0 debemos activar la opción que por defecto viene desactivada