Unit Testing ASP.NET? ASP.NET unit testing has never been this easy

mayo 18, 2009 10:35 by Admin
Typemock is launching a new product for ASP.NET developers – the ASP.NET Bundle - and for the launch will be giving out FREE licenses to bloggers and their readers.

The ASP.NET Bundle is the ultimate ASP.NET unit testing solution, and offers both
Typemock Isolator, a unit test tool and Ivonna, the Isolator add-on for ASP.NET unit testing, for a bargain price.

Typemock Isolator is a leading
.NET unit testing tool (C# and VB.NET) for many ‘hard to test’ technologies such as SharePoint, ASP.NET, MVC, WCF, WPF, Silverlight and more. Note that for unit testing Silverlight there is an open source Isolator add-on called SilverUnit.

The first 60 bloggers who will blog this text in their blog and
tell us about it, will get a Free Isolator ASP.NET Bundle license (Typemock Isolator + Ivonna). If you post this in an ASP.NET dedicated blog, you'll get a license automatically (even if more than 60 submit) during the first week of this announcement.

Also 8 bloggers will get an additional 2 licenses (each) to give away to their readers / friends.

Go ahead, click the following link for
more information on how to get your free license.

Sea el primero en calificar este post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

‘Aplicaciones Dinámicas’ con .NET Reflection y su Rendimiento

febrero 11, 2009 06:38 by Admin

Enviado por Johnatan Flores Carmona el 19 de enero de 2009 

Saludos a todos, antes que nada quisiera comentar que felicito a los propietarios de este grupo así cómo a los usuarios por esta nueva etapa ahora en 'Live'. He sido miembro de este grupo desde ya algunos años y aunque mi participación ha sido casí nula me gustaria pensar "Año Nuevo, Grupo Nuevo, Actitud Nueva" así que para empezar con la nueva actitud, me gustaría compartir con ustedes algo que he tenido que a prender por las malas: El maravillos mundo de .NET Reflection........

Problema:

Actualmente en la institución donde laboro me asignaron a un proyecto que consiste en construir un ‘Bridge’ para que la aplicación ‘X’ pudiera comunicarse con la aplicación ‘Y’. Uno de los muchos requerimientos que solicitaron fue: ‘Actualmente debes conectar ‘X’ con ‘Y’, pero este bridge debe servir posteriormente para comunicar a ‘W’ con ‘Z’, ‘Y’ con ‘W’, etc. por lo que debe ser una aplicación que su funcionalidad deba ser configurable desde base de datos. ¿Cuál fue la solución a estos requerimientos?  R:= .NET Reflection. 

Solución con Reflection:

Implementaciones: Cada uno de las aplicaciones (W, X, Y, Z) tiene sus propias ‘reglas’ de comunicación, por lo que para comunicar XàY se requiere una ‘implementación’ diferente que para comunicar a WàZ y otra totalmente diferente para YàW.

Interfaz de implementación: Todas las implementaciones deberán exponer un método llamado ‘Ejecutar’ el cuál servirá para llevar a cabo los procesos necesarios para cada una de las implementaciones.

Fabrica de implementaciones: Se requiere un método que nos permita obtener la implementación correcta en base a los parámetros de entrada (posiblemente un ID o un nombre).

Diccionario de implementaciones: Requerimos un diccionario que nos permitirá conocer el nombre de la clase que deseamos utilizar para realizar la implementación correcta (en nuestro caso una base de datos o un archivo xml).

Prueba: El método Main que realiza la prueba (hipotetica) de esta solución sería de la siguiente manera:

    class TestRendimientoReflection

    {

        static void Main(string[] args)

        {

            

            //Codigo para medir el tiempo de ejecucion

            EjecutarTest(totalIteraciones);

        }

        static void EjecutarTest(int totalIteraciones)

        {

            Random generadorIdentificadores = new Random();

            for (int i = 0; i < totalIteraciones; i++)

            {

                int idClase = generadorIdentificadores.Next(1, 11);

                IImplementacion clase = FabricaImplementacion.CrearImplementacion(idClase);

                Console.WriteLine(clase.Ejecutar());

            }

        }

    }

Solución sin Reflection:

Implementaciones: (Igual que con Reflection)

Interfaz de implementación: (Igual que con Reflection)

Prueba: El método Main que realiza la prueba de esta solución (hipotetica) sería de la siguiente manera:

    class TestRendimientoSinReflection

    {

        static void Main(string[] args)

        {

            

            //Codigo para medir el tiempo de ejecucion 

            EjecutarTest(totalIteraciones);

        }

        static void EjecutarTest(int totalIteraciones)

        {

            Random generadorIdentificadores = new Random();

            for (int i = 0; i < totalIteraciones; i++)

            {

                int idClase = generadorIdentificadores.Next(1, 11);

                IImplementacion clase = null;

                switch (idClase)

                {

                    case 1:

                        clase = new Implementacion01();

                        break;

                    case 2:

                        clase = new Implementacion02();

                        break;

                    //Todos los case necesarios

                    default:

                        clase = new Implementacion10();

                        break;

                }

                Console.WriteLine(clase.Ejecutar());

            }

        }

    }

Rendimiento:

Cuando se me cuestionó sobre si la utilización de Reflection afectaría el rendimiento que podría tener la aplicación tuve que investigar sobre dicho tema y encontré la siguiente referencia: .Net Reflection and Performance

En este enlace menciona que los procesos de obtener y asignar valores a propiedades con reflection resultó de 2.5 a 3 veces más lento que hacerlo directamente; además de que la invocación de métodos fue 3.5 a 4 veces más lento con reflection que realizar una llamada directa al método.

Estos resultados claramente no son satisfactorios para una aplicación que posiblemente tendría que atender cientos o miles de peticiones, pero también no es nuestro caso la asignación o lectura de propiedades ni mucho menos la ejecución de métodos utilizando reflection. Los datos que necesitábamos conocer era el rendimiento al instanciar clases utilizando reflection.

A continuación los datos que fueron obtenidos:

Rendimiento de Reflection
  Prueba con Reflection Prueba sin Reflection
Total iteraciones 10,000 10,000
Total de Pruebas 20 20
Promedio (ms): 3,813.44 3,706.60
Media (ms): 3,793.24 3,592.44
Mediana (ms): 3,914.25 3,867.38

 Con estos datos se puede decir que el rendimiento de instanciar clases utilizando reflection es de 0.01 a 0.06 veces más lento que creando las instancias directamente. 

Beneficios:

A continuación mencionaré algunas métricas que son utilizadas en el desarrollo de software que están ligadas al código fuente y cómo el uso de Reflection podria ayudar a mejorarlas:

Mantenibilidad: Cómo se puede observar, ambos códigos (con Reflection y sin él) son fácilmente mantenibles ya que si existe un cambio en los procesos de una implementación, sólo tendríamos que modificar la clase correspondiente.

Complejidad Ciclomática: Esta métrica se ve mejorada al utilizar reflection ya que cómo podemos observar no necesitaremos la sentencia ‘switch / case’ para la creación de los objetos con las implementaciones deseadas.

Líneas de código: Las líneas de código también se ven reducidas considerablemente al hacer uso de Reflection.  }

Bajo acoplamiento: Debido a que la construcción se basa en un 'diccionario' de implementaciones, si se deseara que los procesos requeridos para comunicar X con Y ya no es la clase 'ImplementacionXY y en su lugar se utilizaría NuevaImplementacionXY; utilizando Reflection sólo se tendría que modificar el diccionario y no todas las porciones de código que hicieran referencia a esa clase (cómo sería con la instanciación directa). 

Conclusiones:

Utilizar .NET Reflection indiscriminadamente en nuestras aplicaciones hará que el rendimiento de ejecución sea bastante pobre; sin embargo, si se planea bien las arquitectura y las estrategias para utilizar .NET Reflection, el costo de utilizar esta poderosa API no es alto si se consideran los beneficios que se pueden obtener.

Si se desea conocer las buenas practicas de programación al utilizar reflection, pueden leer este excelente artículo: Dodge Common Performance Pitfalls to Craft Speedy Applications

Código Fuente:


Actualmente calificado con 5.0 por 1 personas

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Qué es ASP .NET Control Extenders?

febrero 11, 2009 06:29 by Admin
Aqui dejamos un aporte de la comunidad enviado a través de la seccion de Foro (foro.barreteros.net), este fue enviado por nuestro amigo Johnatan Flores Carmona [johnatan.jfk@gmail.com], el es un Desarrollador .NET de la ciudad de León Guanajuato, aquí dejo el aporte:
------------------------------------------------------------------------------------------
Saludos a todos de nuevo, espero que tengan un bonito día festivo. Y ya que yo tuve que venir a trabajar a pesar de que toda la empresa descansó, estoy aquí para compartir con ustedes otro tema que tuve que investigar hace un tiempo, espero les sea de utilidad. 

  

Qué es ASP .NET Control Extenders?

ASP .NET Control Extenders son controles que derivan de la clase base ExtenderControl (System.Web.UI) la cual puede ser usada para agregar funcionalidad adicional (usualmente soporte AJAX o JavaScript) a controles declarados dentro de una pagina. Esto habilita a los desarrolladores el encapsulamiento de comportamientos IU, y hacer muy fácil agregar funcionalidad a una aplicación web. Un ejemplo de esto es el ASP .NET AJAX Control Toolkit (1)

Según MSDN Library: "La clase ExtenderControl permite mediante programación agregar funcionalidad AJAX a un control de servidor ASP .NET. El ExtenderControl hereda desde la clase Control e implementa la interfaz IExtenderControl. La clase Control define las propiedades, métodos y eventos que son compartidos por todos los controles de servidor ASP .NET. La interfaz IExtenderControl es una clase abstracta la cual no puede ser instanciada directamente. En su lugar debes crear un tipo derivado." (2)

  

Pasos para crear un control extendido

  1. Crear clase abstracta base que hereda ExtenderControl
  2. Crear el archivo .js que implementará el comportamiento de IU (ECMAScript)
  3. Crear una clase que herede de la clase creada en 1 la cual será el extensor del control.
  4. Utilizar el control en una pagina .aspx

En las siguientes secciones se explicarán los pasos necesarios para crear un extensor de control que permite cambiar el estilo al control cuando el mouse pase encima de el.

  

Crear clase base que hereda de ExtenderControl

Cuando se crea una clase que herede de ExtenderControl se requiere que se implementen los métodos abstractos GetScriptDescriptor y GetScriptReferences.

public abstract class ExtenderControlBase : ExtenderControl
{
   protected override IEnumerable<ScriptDescriptor> GetScriptDescriptors(Control targetControl)
   {
      throw new NotImplementedException();
   }
   protected override IEnumerable<ScriptReference> GetScriptReferences()
   {
   throw new NotImplementedException();
   }
}
  • GetScriptDescriptor: Método usado para obtener una colección de descriptores script que representan los componentes cliente ECMAScript (JavaScript).
  • GetScriptReferences: Método usado para obtener una colección de objetos ScriptReference que definen los recursos script que el control requiere.

  

GetScriptDescriptors

Este método debe regresar una colección de objetos ScriptDescriptor que definen que propiedades serán pasadas a la representación del control en el lado del cliente.

protected override IEnumerable<ScriptDescriptor> GetScriptDescriptors(Control targetControl)
{
   ScriptControlDescriptor descriptor = new ScriptControlDescriptor(this.GetType     
                                          ().FullName, targetControl.ClientID);
   descriptor.AddProperty("id", this.ClientID);
   PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(this);
   foreach (PropertyDescriptor property in properties)
   {
      ExtenderControlPropertyAttribute propertyAttribute =
            property.Attributes[typeof(ExtenderControlPropertyAttribute)] as
            ExtenderControlPropertyAttribute;
      if (propertyAttribute != null)
      {
          object value = property.GetValue(this);
          string name = (propertyAttribute.Name != null) ?
                            propertyAttribute.Name : property.Name;
      if (value != null)
             descriptor.AddProperty(name, value);
   }
   }
   yield return descriptor;
}

En el código anterior se crea el objeto que contendrá todas las propiedades que contendrá nuestro control; para ello se obtiene la colección de propiedades que contiene nuestra clase (la clase hija que se creará en el paso 2). Una vez obtenida la colección se recorrerán cada uno de los objetos contenidos y se agregan al descriptor con el método .AddProperty

  

GetScriptReferences

Este método regresará una colección de objetos ScriptReference para incluirlos en la pagina del lado del cliente.

protected override IEnumerable<ScriptReference> GetScriptReferences()
{
   object[] scriptReferences = Attribute.GetCustomAttribute(
   this.GetType(), typeof(ScriptReferenceAttribute), false);
   foreach (ScriptReferenceAttribute sra in scriptReferences)
       yield return sra.GetScriptReference();
}

  

Crear el archivo ECMAScript

Este archivo es el que contiene todo el código (JavaScript) que controla los comportamientos que tendrá el control extendido. A continuación se presenta el bloque de código base que debe tener este archivo.

Type.registerNamespace("CustomAjaxControlKit");
CustomAjaxControlKit.MouseOverExtender = function(element){
   CustomAjaxControlKit.MouseOverExtender.initializeBase(this,[element]);
};
CustomAjaxControlKit.MouseOverExtender.prototype = {
   initialize: function(){
      CustomAjaxControlKit.MouseOverExtender.callBaseMethod(this, "initialize");
   },
   dispose: function(){
      CustomAjaxControlKit.MouseOverExtender.callBaseMethod(this, "dispose");
   }
};
CustomAjaxControlKit.MouseOverExtender.registerClass  
      ("CustomAjaxControlKit.MouseOverExtender", Sys.UI.Behavior);
Sys.Application.notifyScriptLoaded();

El código anterior debe modificarse para que se vea cómo el código siguiente:

Type.registerNamespace("CustomAjaxControlKit");
CustomAjaxControlKit.MouseOverExtender = function(element){
   CustomAjaxControlKit.MouseOverExtender.initializeBase(this, [element]);
   this._MouseOverCssClass = null;
   this._MouseOutCssClass = null;
   this._mouseOverHandler = Function.createDelegate(this, this._onMouseOver);
   this._mouseOutHandler = Function.createDelegate(this, this._onMouseOut);
};
CustomAjaxControlKit.MouseOverExtender.prototype = {
   initialize: function(){
      CustomAjaxControlKit.MouseOverExtender.callBaseMethod(this, "initialize");
      var targetElement = this.get_element();
      $addHandler(targetElement, "mouseover", this._mouseOverHandler);
      $addHandler(targetElement, "mouseout", this._mouseOutHandler);
},
   dispose: function(){
      var targetElement = this.get_element();
      $removeHandler(targetElement, "mouseover", this._mouseOverHandler);
      $removeHandler(targetElement, "mouseout", this._mouseOutHandler);
      CustomAjaxControlKit.MouseOverExtender.callBaseMethod(this, "dispose");
   },
   get_MouseOverCssClass: function(){
      return this._MouseOverCssClass;
   },
   set_MouseOverCssClass: function(value){
      this._MouseOverCssClass = value;
   },
   get_MouseOutCssClass: function(){
      return this._MouseOutCssClass;
   },
   set_MouseOutCssClass: function(value){
      this._MouseOutCssClass = value;
   },
   _onMouseOver: function(eventArgs){
      var targetElement = this.get_element();
      if(targetElement != null)
         targetElement.className = this.get_MouseOverCssClass();
   },
   _onMouseOut: function(eventArgs){
      var targetElement = this.get_element();
      if(targetElement != null)
         targetElement.className = this.get_MouseOutCssClass();
   }
};
CustomAjaxControlKit.MouseOverExtender.registerClass     
                     ("CustomAjaxControlKit.MouseOverExtender", Sys.UI.Behavior);
Sys.Application.notifyScriptLoaded();

  

Crear la clase que será el extensor del control

Debido a que se creó una clase abstracta base que hereda de la clase ExtenderControl (véase el paso 1), la creación de nuestra clase que será el extensor de control simplemente debe agregar la WebReference del archivo ECMAScript, heredar la clase ExtenderControlBase y agregar las declaraciones de las propiedades que tendrá nuestro extensor de control.

A continuación se muestra el código de nuestra clase:

[assembly: WebResource("CustomAjaxControlKit.MouseOver.MouseOverBehavior.js",
                                                         "text/javascript")]
namespace CustomAjaxControlKit
{
   [TargetControlType(typeof(Control)), ScriptReference(
        "CustomAjaxControlKit.MouseOver.MouseOverBehavior.js", CustomAjaxControlKit")]
   public class MouseOverExtender : ExtenderControlBase
   {
      [ExtenderControlProperty]
      public string MouseOverCssClass { get; set; }
      [ExtenderControlProperty]
      public string MouseOutCssClass { get; set; }
   }
}

  

Utilizar el extensor de control en una pagina .aspx

Para poder utilizar nuestro extensor de control en una pagina .aspx tenemos que primero agregar la referencia al dll que contiene el código de nuestro extensor. Una vez realizado esto se debe incluir la directiva @Register para poder incluir en la pagina los tags de nuestro control: 

<%@ Register Assembly="CustomAjaxControlKit" Namespace="CustomAjaxControlKit" TagPrefix="cack" %>
Por último debemos agregar el control que sufrirá los efectos de nuestro extensor y a continuación declarar nuestro control:
<asp:Label runat="server" ID="Label1" Text="Texto prueba" />
<cack:MouseOverExtender ID="MouseOverExtender1" runat="server" TargetControlID="Label1"  MouseOutCssClass="MouseOutStyle"
                       MouseOverCssClass="MouseOverStyle" />

  

Ejemplo: Codigo Fuente

Si deseas ver el código fuente completo de este control puedes descrgarlo en el siguiente link:

  

Referencias

  1. ScottGu; Using ASP .NET AJAX Control Extenders in VS 2008; http://weblogs.asp.net/scottgu/archive/2007/08/19/using-asp-net-ajax-control-extenders-in-vs-2008.aspx
  2. MSDN Library; About ExtenderControl Class; http://msdn.microsoft.com/en-us/library/system.web.ui.extendercontrol.aspx

Sea el primero en calificar este post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Material Curso ASP.NET ITZ 2008

octubre 24, 2008 05:10 by Admin

Revisión de material de Curso .NET ITZ 2008
Ya está disponible la revisión del proyecto “HolaMundo”

PaqueteZIPHolaMundo
Contenido del paquete:

  • Conociendo controles HTML y ASP .NET
  • Conociendo el concepto de Postback
  • Uso de controles HTML y ASP.NET combinados
  • Manteniendo estado de controles entre postbacks

Click para descargar: HolaMundo.zip


Sea el primero en calificar este post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Material Curso ASP.NET ITZ 2008

octubre 24, 2008 05:10 by Admin

Material del Curso ASP.NET ITZ 2008
Tercera Sesion 21 de Octubre de 2008

Introducción a la plataforma .NET de Microsoft Introducción a la plataforma .NET de Microsoft
Temas analizados:

  • Conceptos básicos ASP.NET
  • Generalidades de HTTP
  • HTML Forms
  • Webforms
  • Controles básicos
  • Programación en Code-Behind

Click para descargar: Office 2007

PaqueteZIPHolaMundo2
Contenido del paquete:

  • Conociendo controles HTML y ASP .NET
  • Conociendo el concepto de Postback
  • Uso de controles HTML y ASP.NET combinados
  • Manteniendo estado de controles entre postbacks

Click para descargar: HolaMundo2.zip

 


Sea el primero en calificar este post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Material 1ra Sesión ya disponible - Curso ASP .NET ITZ 2008

octubre 15, 2008 16:00 by Admin

Material de la 1ra clase Curso ASP .NET ITZ 2008


Ya está disponible el material correspondiente a la clase del Martes 14 de Octubre de 2008.

Qué tal a todos. Ya están disponibles las presentaciones de diapositivas correspondientes a la primera clase para todos los asistentes al Curso .ASP.NET que se lleva a cabo en el Instituto Tecnológico de Zacatecas.

En esta primera clase se analizaron conceptos básicos  de los elementos principales de los que consiste la plataforma .NET de Microsoft.

Introducción a la plataforma .NET de Microsoft Introducción a la plataforma .NET de Microsoft
Temas analizados:

  • Introducción a Microsoft .NET
  • Componentes fundamentales
  • Arquitectura del .NET Framework
  • Funcionamiento del CLR
  • Bibliotecas de clase principales
  • Sistema de Tipos Comunes (CTS)

Click para descargar: Office 2007


Sea el primero en calificar este post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Welcome to BlogEngine.NET 1.3

diciembre 21, 2007 18:00 by Admin

If you see this post it means that BlogEngine.NET 1.3 is running and the hard part of creating your own blog is done. There is only one thing you need to do from this point on to take full advantage of the blog and that is to set up the first author profile.

Write Permissions

To be able to log in to the blog and writing posts, you need to enable write permissions on the App_Data folder. If you’re blog is hosted at a hosting provider, you can either log into your account’s admin page or call the support. You need write permissions on the App_Data folder because all posts and comments are saved as XML files and placed in the App_Data folder.

Username and password

When you've got write permissions to the App_Data folder, you need to change the username and password. Find the sign-in link located either at the bottom or top of the page depending on your current theme and click it. Now enter "admin" in both the username and password fields and click the button. You will now see an admin menu appear. It has a link to the "Users" admin page. From there you can change the username and password.

On the web

You can find BlogEngine.NET on the official website. Here you'll find tutorials, documentation, tips and tricks and much more. The ongoing development of BlogEngine.NET can be followed at CodePlex where the daily builds will be published for anyone to download.

Good luck and happy writing.

The BlogEngine.NET team


Actualmente calificado con 4.4 por 3 personas

  • Currently 4,4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5