WCF TIPS - Como generar una descarga http estándar y hostearla desde un servicio

por maxi  20. septiembre 2010

    Objectivo: Crear un ejemplo de servicio con WCF que permita a un navegador descargar un archivo por http en forma estándar.

    Características del servicio:

    • Self-Host: En este caso va a ser Self-host  en una aplicacion Winforms asi puede ser hosteado en cualquier maquina sin necesidad de configurar un IIS.

    • REST: No se utilizara SOA, ya que REST es más liviano dado que el mensaje no tiene toda la información del Envelope SOAP.

      Streamming: El servicio enviará el archivo en mediante Streamming lo que permite manejar archivos grandes.

    • Multithreading: el servicio no será Single es decir una instancia del servicio atenderá cada llamada, de esta forma el servicio no encolara las solicitudes si no que podrá atender varias descargas al mismo tiempo y a diferentes clientes.

      Lo primero que haremos será crear el contrato, al que llame IDownloadService que contiene el método DownloadFileHttp, el cual recibe el path y el nombre del archivo para descargar y retornara el Stream.

      Esta claro que no es ideal recibir el path del archivo en el servicio, pero lo hice para ejemplificar como recibir varios parametros ya que este servicio utiliza REST por lo cual el servicio recibe los parametros en forma de query string. El atributo WebGet precisamente nos permite definir que el servicio recibira la solicitud mediante una url de la siguiente forma:

                                       DirecciónBase           / download    / path / fileName

      P.e.: http://localhost:9000/DownloadService / download    / C:@mp3  /   tema.mp3

       
           [ServiceContract]
          public interface IDownloadService
          {
              [OperationContract]
              [WebGet(UriTemplate = "download/{path}/{fileName}")]
              Stream DownloadFileHttp(string path, string fileName);
          }
       

      Una vez definido el contrato vamos  a implementarlo de la siguiente manera:

       
        [ServiceBehavior(
              //Cada solicitud crea una nueva instancia de StreamerSvc y se recicla despeus de la llamada 
              //De esta forma las llamadas no se encolan se puede atender a varios clientes
              InstanceContextMode = InstanceContextMode.PerCall,
              //La instancia del servicio es multi threaded
              //Los threads pueden llamar a cualquier operacion del servicio en cualquier momento
              //Multiple implica que le programador tiene que manejar la sincronizacion con locks
              //Pero como el servicio no maneja estados, p.e. variables o atributo de clase no me afecta
              ConcurrencyMode = ConcurrencyMode.Multiple,
              //Esta propiedad hay que setearla en este ejemplo ya que el servicio esta siendo hosteado en una aplicacon Winforms
              //Implica que todas las llamadas al servicio correran en el mismo thread de la UI que creo el servicio (new ServiceHost(...)))
              //La pongo en false para evitar deadlocks ya que por defecto es true
              UseSynchronizationContext = false)]    public class DownloadSvc : IDownloadStream
          {
              public Stream DownloadFileHttp(string path, string fileName)
              {
      //Truco para poder poner el path en la url solo para este ejemplo
                      path = path.Replace("@", @"\");@", @"\");File does not exists!");application/download";content-disposition", string.Format("attachment;filename=\"{0}\"", fileName));
                      fileName = fileName.Replace("
                      path = Path.Combine(path, fileName);
       
                      if (!File.Exists(path))
                      {
                          throw new FaultException("
                      }
              
                      //Abrimos el archivo 
                      var fileStream = File.OpenRead(path);
       
                      //Configurar Headers para el cliente p.e. un browser
                      var headers = WebOperationContext.Current.OutgoingResponse.Headers;
                      WebOperationContext.Current.OutgoingResponse.ContentType = "
                      headers.Add("
                      headers.Add("content-length", fileStream.Length.ToString());
       
               //Retonranos FileStream
                      return fileStream;
              }}
        

      Muy bonito pero para que todo esto funcione correctamente debemos configurar nuestro servicio. Para esto vamos a setear las siguientes entradas en el config:

       
      <?xml version="1.0" encoding="utf-8"?>
      <configuration>
               <system.serviceModel>
                         <bindings>
                                  <mexHttpBinding>
                                            <binding name="MetadataBinding" />
                                  </mexHttpBinding>
                                  <webHttpBinding>
                                            <binding name="DownloadBinding" sendTimeout="00:10:00" maxBufferPoolSize="2147483647"
                                             maxReceivedMessageSize="2147483647" transferMode="Streamed">
                                            </binding>
                                  </webHttpBinding>
                         </bindings>
                         <services>
                                  <service behaviorConfiguration="ServiceBehavior" name="StreamerSvcHost.StreamerSvc">                             
                                            <endpoint address="mex" binding="mexHttpBinding" bindingConfiguration="MetadataBinding"
                                             name="MetadataEndpoint" contract="IMetadataExchange" />
                                            <endpoint address="FileSvc" behaviorConfiguration="RestBehavior"
                                             binding="webHttpBinding" bindingConfiguration="DownloadBinding"
                                             name="DownloadEndpoint" contract="StreamerSvcHost.IDownloadService" />
                                            <host>
                                                     <baseAddresses>
                                                              <add baseAddress="http://localhost:9000/" />
                                                     </baseAddresses>
                                            </host>
                                  </service>
                         </services>
                         <behaviors>
                                  <endpointBehaviors>
                                            <behavior name="RestBehavior">
                                                     <webHttp />
                                            </behavior>
                                  </endpointBehaviors>
                                  <serviceBehaviors>
                                            <behavior name="ServiceBehavior">
                                                     <serviceMetadata httpGetEnabled="true" />
                                                     <serviceDebug includeExceptionDetailInFaults="true" />
                                                     <dataContractSerializer maxItemsInObjectGraph="2147483647" />
                                            </behavior>
                                  </serviceBehaviors>
                         </behaviors>
               </system.serviceModel>

      </configuration>

       

        Lo destacable es lo siguiente:

        • El endpoint deberá tener un webHttpBinding, esto permite exponer el servicio para ser accedido mediante HTTP requests  en lugar de mensajes SOAP.

        • El binding se deberá configurar con TransferMode = Streamed

        • El endpoint deberá tener configura un EndpointBehavior agregándole le elemento webHttp, para que un cliente pueda comunicarse por http con el servicio este debe tener asociado este comportamiento.

        Tags: , , , , , ,

        WCF

        WCF Tips - Clases definidas en el servicio que no aparecen en el proxy del cliente?

        por maxi  14. septiembre 2010

        Cuando generamos una referencia a un servicio en un proyecto de Visual Studio se genera un proxy con todos los métodos definidos en el ServiceContract y las clases definidas como DataContract.
        Los DataContract aparecen en el proxy cuando son recibidos o retornados por algún método de la interfaz. En caso contrario no se generará ya que no aparece en la metadata del servicio.

        Si por algun caso en particular, nosotros utilizamos alguna clase o un enum en un proceso del servicio y este no es recibido ni retornado por ningun metodo y quisieramos utilizarlo del lado, es decir en el cliente,
        estaríamos obligados a duplicarlos manualmente. Por lo tanto vamos a querer que se generen en el proxy del cliente y para lograr esto debemos hacer lo siguiente:

        Primero, generamos una clase que va a contener un método que retornará la lista de clases que serán agregadas a la metadata del servicio. Luego implementamos el método correspoindiente el cual debe retornar una lista de Types, IEnumerable<Type>, y recibirá como parametro un ICustomAttributeProvider. Internamente creamos una lista donde agregamos los Type deseados como se muestra a continuación:

         

         

         

           1:      public static class EnumHelper
           2:      {
           3:          /// <summary>
           4:          /// Obtiene una lista de tipos conocidos que se requieren publicar al cliente
           5:          /// </summary>
           6:          /// <param name="provider"></param>
           7:          /// <returns></returns>
           8:          public static IEnumerable<Type> ObtenerTiposConocidos(ICustomAttributeProvider provider)
           9:          {
          10:              //Incluir los tipos que se requiere ver en el cliente
          11:              var tiposConocidos = new List<Type>
          12:                                              {
          13:                                                  typeof (CodigosMovEnum),
          14:                                                  typeof (Etc)
          15:                                              };
          16:   
          17:              return tiposConocidos;
          18:          }
          19:      }


         

        Segundo, debemos agregar el Atributo ServiceKnownType a nuestro contrato de servicio. Y vamos a pasar como parámetros, primero el Metodo que retorna los Types de las clases que serán agregadas

        en la metadata del servicio y luego, el Type de la clase que contiene dicho método que en este caso es EnumHelper como se muestra a continuación:

         

           1:      [ServiceKnownType("ObtenerTiposConocidos", typeof(EnumHelper))]
           2:      [ServiceContract]
           3:      public partial interface IMiServiceContract
           4:     {    
           5:     }

         

        Luego compilamos el servicio y al actualizar la referencia al proxy del cliente apareceran estas nuevas clases.

         

        Tags: ,

        WCF Tips - Enum definirlo en el servicio y utilizarlo en el cliente

        por maxi  14. septiembre 2010

        Para utilizar un enum simplemente lo definimos y agregamos el atributo DataContract. A cada valor del enum le definimos el atributo EnumMember.

        De esta forma si este enum se recibe como parámetro o es retornado por un metodo del servicio, se generará en la referencia al servicio del cliente.

         

            [DataContract]
        public enum CodigosMovEnum
        {
        [EnumMember]
        Ninguno = 0,

        [EnumMember]
        AEntregar = 1,

        [EnumMember]
        ACumplir = 2,

        }

        Tags: ,

        WCF

        Problemas para compartir archivos? He aquí una herramienta salvadora!

        por maxi  22. enero 2010

        Hay ocaciones cuando necesitamos compartir rapidamente archivos entre pcs de escritorio, notebooks y/o dispositivos móviles.Ya sea dentro de la red interna o con otro usuario que utiliza internet. Si estamos en una LAN incluso podemos tener problemas de seguridad con firewalls, carpetas compartidas y dependiendo si estamos en un dominio o no, con las cuentas para acceder a estos recursos en la máquina remota. Ni hablar de compartir archivos entre máquinas con distintos sistemas operativos o contra celulares por ejemplo. Si queremos compartir un archivo con un usuario de internet que esta fuera de la LAN tenemos varias alternativas, por ejemplo: FTP, MSN, Google Talk (La versión en inglés permite transferir archivos!), Rapidshare!?. Bueno como todos sabemos puede que el receptor no tenga posibilidades de utilizar ninguna de estas herramientas o podemos tener problemas de lentitud.

         

        Encontré esta herramienta muy interesante llamada HFS,  que  permite publicar los archivos deseados generando un link para que el usuario remoto haga una descarga común http. No necesitamos ninguna infraestructura especial, ni IIS, apache, JRE, nada extraño, la herramienta se encarga de hostear el archivo.

         

        Se puede descargar de: http://www.rejetto.com/hfs/

         

        Espero que les sea útil!

         

         

        Tags:

        Tecnología

        El uso de múltiples monitores incrementa la productividad

        por maxi  22. enero 2010

        Un estudio realizado por NEC, ATI y la Universidad de Utah concluye que el uso de múltiples monitores incrementa la productividad

         

        El Dr. James Anderson, profesor del departamento de Comunicaciones de la Universidad de Utah afirma:

        “El estudio revela que los usuarios de pantallas múltiples trabajan más rápido, 

        realizan más tareas y con menos errores al editar documentos,

        planillas de cálculo y edición de imágenes en comparación a los usuarios de una sola pantalla.”


        Los principales resultados del estudio arrojaron que los participantes, utilizando una configuración de múltiples monitores:

        • Fueron 10% más productivos.
        • Disminuyeron sus errores de edición en un 18%.
        • Fueron un 29% más efectivos al realizar sus tareas.
        • Se sintieron un 24% más cómodos al usar esta configuración para realizar su trabajo.
        • En un 39% les fue más fácil mover ya acomodar sus fuentes de información.


        El estudio menciona los siguientes beneficios de los puestos de trabajo con múltiples monitores:

        • Permite procesar múltiples fuentes de información en forma simultánea, mover y cambiar su tamaño en una o todas las pantallas disponibles para incrementar la productividad.
        • Puede impactar en el ROI de la empresa si se considera la disminución de los errores en cada puesto de trabajo
        • Puede impactar positivamente en la moral de los trabajadores haciendo que se sientan más cómodos y hábiles para completar sus tareas permitiéndoles una navegación más ágil y un enfoque mayor en sus tareas.
        • Tiene una curva de aprendizaje muy baja.


        Aplicaciones inmediatas para el desarrollo de software

        Podríamos utilizar una pantalla para tener maximizado nuestro entorno de desarrollo y al mismo tiempo, en la otra pantalla, tener un documento con los requerimientos, buscar en internet con un navegador, hacer consultas sobre la BD, etc. Interesante no?

         

        Ahora que está demostrado científicamente tal vez las empresas puedan hacer una buena inversión!

        Quien se anima a llenar la F-10? (Chiste interno – solo para entendidos!)

         

        Para más detalles se pueden consultar las siguientes fuentes

        http://www.necus.com/necus/media/press_releases/template.cfm?DID=1947

        http://www.nytimes.com/2006/04/20/technology/20basics.html

        http://www.tufuncion.com/dos-monitores

        http://www.youtube.com/watch?v=TVVLzaMMqRM


        Tags: ,

        Tecnología

        Lectura recomendada “SOA in Practice” de Nicolai M. Josuttis

        por maxi  22. enero 2010

         

        Recientemente he comenzado a leer este libro y la verdad es que quisiera recomendarlo. Tanto para quienes estén por arrancar con un proyecto SOA como para quienes ya estén plenamente involucrados con este tipo de arquitectura, como es mi caso. La verdad es que me siento representado por las vivencias del autor y me parece importante compartir algunas conclusiones iniciales.

        Aclaro que en esta primera parte solo me voy a referir a temas conceptuales y de gestión, no a detalles técnicos ni tecnologías específicas.

         

        Que es SOA?

        En este caso coincido totalmente cuando el autor dice que hay infinidad de definiciones y lo principal es quedarse con la idea importante de SOA.

        SOA es un paradigma para el diseño de la arquitectura de nuestros sistemas que permite orquestar y mantener grandes sistemas distribuidos. Para entender SOA hay que entender las características de los grandes sistemas, donde tenemos que luchar con los viejos sistemas legados, la mayoría de los cuales inicialmente van a seguir operativos. No podemos hacer todo desde cero desde el comienzo y por esto vamos a tener que trabajar en conjunto las plataformas viejas y temas de compatibilidad.


        Por qué SOA?

        SOA permite que los sistemas de la organización sean flexibles mientras crecen,  interoperar y orquestarse de forma más sencilla.  Esto es referido tanto a los sistemas internos de la organización como con sistemas externos como ser clientes, proveedores, gobierno, etc.

        Determinadas  organizaciones cuentan con sistemas grandes, complejos y heterogéneos, es decir,  utilizan una variedad de tecnologías diferentes  y con mucha longevidad. Eventualmente el costo de mantenimiento ya sea para incorporar nuevas funcionalidades como para interconectarse con otros sistemas se hace muy grande. Principalmente debido a la cantidad de “conexiones” que estos sistemas utilizan para interactuar con otros o para implementar diferentes funcionalidades y  donde cada uno puede usar tecnologías muy diferentes.

         

        Conceptos

        El autor presenta como los elementos más importantes:

        • Los Servicios, son unidades que contienen funcionalidad de negocio, construidos sobre los principios y  pilares de este estilo de arquitectura y que pueden ser implementados con diferentes tecnologías y plataformas.

         

        • Una infraestructura específica, llamada Enterprise Service Bus (ESB). El ESB está formado por la infraestructura que permite a los sistemas interoperar. Si bien parece complicado, en realidad es simplemente una abstracción, es una línea base, común para interconectar nuestros servicios y consumirlos.   Son los puntos de conexión a nuestros servicios, sus detalles tecnológicos, interfaces, seguridad, framework, etc. En otras palabras, soporta los conceptos de interoperabilidad y desacople. El desacople es un concepto que permite reducir las dependencias entre los sistemas para disminuir los efectos de las modificaciones y de los fallos. Para lograrlo, se debe pagar un precio  que consiste en aumentar la complejidad. Esto se traduce en más dificultad de desarrollo, mantenimiento y debug.


         

        Figure 1 Enterprise Service Bus

         

        • Políticas y procesos, que permiten crear y mantener estos servicios que pueden ser heterogéneos y que tienen diferentes “owners”.

         

        No se debe perder de vista que cuando trabajamos con SOA,  tenemos una arquitectura que abarca servicios, infraestructura de redes, servidores, seguridad, políticas y procesos para su gestión, etc. Todo esto debe estar a la medida del desafío.

        Hay que tener en cuenta que una arquitectura distribuida es compleja por sí misma y abarca muchas disciplinas de IT. Es por esto que considero importantísimo a la hora de aplicar SOA hacer una clara definición de los roles, equipos involucrados y políticas de colaboración.

        No sólo vamos a tener equipos de desarrollo, es necesario tener un equipo de arquitectura encargado del ESB, un equipo que se ocupe de definir políticas y procesos,  un equipo de infraestructura (Administradores de servidores, redes y seguridad). También se debe definir los referentes tecnológicos (Conocedores de las plataformas, lenguajes de programación, etc.) y los sponsors (Gerentes, Líderes de proyecto, etc.), que son quienes nos brindan los recursos (tiempo y dinero).

        Un concepto interesante que introduce el autor es el de owner, como el  equipo que  dueño del servicio está encargado de su desarrollo, que aplica las políticas y que utiliza los procesos definidos. Cada owner maneja diferentes presupuestos, tiempos, visiones e intereses que hay que considerar. Y es necesario que estos owners colaboren con otros para poder orquestar y ampliar las funcionalidades de sus sistemas. Esta colaboración no sólo abarca a los owners si no también al equipo de arquitectura y al personal de infraestructura. Por esto las políticas y los procesos son iguales o más importantes que el conocimiento de la tecnología.


        Como dice el autor “…Una vez que se comprende como implementar SOA, no es difícil,  pero toma tiempo y coraje (OK, entonces es difícil). Cuesta mucho esfuerzo ayudar a la gente a que comprenda el paradigma (comenzando por uno mismo) y si no estás dispuesto a hacer el esfuerzo fallarás…”

         

        Gobernance

        El autor destaca los siguientes puntos para la administración SOA:

        • Se necesita tener un equipo central para determinar los aspectos generales de SOA  de la organización. El objetivo debe ser lograr la descentralización de los sistemas grandes.

         

        • Se debe contar con el personal adecuado y con experiencia en sistemas grandes, de manera que puedan tomar decisiones prácticas relacionadas con ellos. Los requerimientos de los equipos de negocio son quienes lo conducen y deben considerarse como sus proveedores.

         

        • No eNo es necesario considerar desde el comienzo la administración de los servicios. Se puede pensar cómo administrarlos cuando se logren tener muchos en funcionamiento. Es decir, no es necesario crear o pensar en toda la infraestructura desde un inicio si no que deben crecer juntos.


        • El  CEO y del CIO (Chief Information Officer) deben apoyar el concepto de SOA. Es decir, se debe contar con el apoyo de la dirección de la organización y de la gerencia de sistemas, para tomar las decisiones adecuadas y que provean el suficiente tiempo y dinero. Tener suficientes fondos a corto plazo no es lo importante. Se necesita dinero a largo plazo dado que cortar el presupuesto de SOA cuando se ha hecho la mitad de las tareas es una receta para el desastre.

         

        Primeras conclusiones

        SOA es un paradigma que tiene que ayudar a la gente de IT a ser flexibles, esto significa brindar soluciones a los requerimientos del negocio oportunamente. Mantener e integrar sistemas grandes y heterogéneos, y sistemas legados hasta que sean reemplazados. Para lograr esto la organización se debe alinear y también los roles, procesos, etc. ya que todos estos aspectos están relacionados.an>

        SOA no es una herramienta o receta que se pueda aplicar para “hacer que todo funcione”. Es un paradigma que se debe desarrollar y aplicar en la organización en su conjunto.

        Tags: , ,

        SOA

        Cómo agregar iconos a los CustomControls para que se vean en la ToolBox

        por maxi  12. marzo 2008

        Muchas veces creamos controles personalizados para utilizar en los formularios.
        A veces estos controles se colocan en un Assembly para ser reutilizado y en otras dentro
        de la propia capa de presentación de nuestra aplicación.
        Por defecto el IDE asigna un engranaje azul como icono en la ToolBox.
        Cuando tenemos muchos controles a veces puede costar encontrar el que queremos.
        Y otras veces solamente por un tema estético podríamos querer asignar un ícono determinado, p.e.
        cuando hacemos un componente de controles para un cliente.

        Podemos fácilmente asignar imágenes a nuestros controles para visualizarlos más rapido desde la
        ToolBox. Para asignar una imagen a un control debemos realizar los siguientes pasos:

        1. Agregar una imagen en los Resources de la Assembly p.e. "MiImagen.ico"
        2. Configurar la imagen como "Embeded resource" desde la property grid
        3. Asignar el atributo "ToolboxBitmap" al control en cuestion. "ToolboxBitmap" puede recibir dos parámetros, el primero "Type" es la clase del control donde el IDE va air a buscar una imagen, el segundo es un string "name" y define una imagen.


        Ejemplos:

        //Esto significa que nuestro control que hereda de TextBox mostrará el icono por defecto
        //que tiene la clase TextBox
        [ToolboxBitmap(typeof(TextBox))]
        public partial class MiControl: TextBox
        {
        }

        //Esto significa que nuestro control que hereda de TextBox mostrará el icono por defecto
        //que tiene la clase Button
        [ToolboxBitmap(typeof(Button))]
        public partial class MiControl: TextBox
        {
        }

        //Esto significa que nuestro control que hereda de TextBox mostrará el icono por defecto
        //que tiene la clase TextBox
        [ToolboxBitmap(typeof(TextBox))]
        public partial class MiControl: TextBox
        {
        }

        //Esto significa que nuestro control que hereda de TextBox mostrará el icono
        //MiImagen que esta definido en los resources
        [ToolboxBitmap(typeof(MiControl), "Resources.MiImagen.ico")]
        public partial class MiControl: TextBox
        {
        }
        Atencion! Los íconos deben ser de 16x16 pixels y por lo que he observado Visual Studio utiliza 256 colores para mostrar los íconos en la ToolBox así que no se esmeren mucho buscando imágenes. Utilizen algún programa que pueda mostrarles como se verá en 256 colores y creen el archivo de imagen correspondiente. Recuerden de configurar la transparencia para que se vea  bien la imagen.
        Para poder visualizar los nuevos íconos lo recomendable es recompilar el Assembly. Luego agregen una Tab en en la ToolBox hacen boton derecho sobre esa Tab y luego "Choose Items"  seleccionan el Assembly y dan Aceptar. A continuación el IDE cargará los controles en la nueva solapa creada.
        Si hacen alguna modificación deben borrar a mano los controles de la Tab y luego repetir la operación anterior.

         

         

        Tags:

        Visual Studio

        PLK - Como obtener la clave de paquete de extensibilidad

        por maxi  10. marzo 2008

         

        Cuando desarrollamos paquetes de extensibilidad para Visual Studio necesitamos obtener una clave conocida como PLK o Package Load Key. En el ambiente de desarrollo podemos probar los componentes de extensibilidad ya que tenemos instalado el kit de desarrollo o SDK de Visual Studio. Pero el usuario final no tiene por qué tener instalado dicho componente.

         

        Microsoft requiere que cada paquete de extensibilidad para Visual Studio tenga una clave generada y registrada por Microsoft. El PLK permite que Microsoft realice un seguimiento de todos los paquetes lanzados por terceras partes a través de su firma. Dado que la clave se genera a partir de los datos registrados esta información debe ser exactamente igual a la declarada en el paquete de extensibilidad de lo contrario no funcionará.

        La clave puede obtenerse gratis desde el sitio Visual Studio Industry Partner (VSIP):

         

        El PLK es una clave que se forma a partir de los datos específicos del paquete de extensibilidad:

        1. Package GUID, o identificador único del paquete.
        2. Package Name, nombre del paquete.
        3. Product Name, nombre del producto.
        4. Company Name, nombre de la empresa que desarrolla el paquete.

         

        Una vez obtenido el PLK desde el sitio mencionado anteriormente, el mismo debe almacenarse en un archivo de recursos del paquete de extensibilidad por ejemplo: “VSPackage.resx”. En este archivo se guarda el string de la clave y se le asigna un ID, como se muestra a continuación.

         

        Ilustración 1 En rojo: donde se coloca el string del PLK

         

         Luego se debe editar la clase del proyecto que herede de “Package” o “PackageBase” y agregarle los atributos “Guid” y “ProvideLoadKey”. Por ejemplo:

         

           1:  [ProvideLoadKey("Standard","1.0.0.0",”AzManDSLTool”, “MaxiMegaCorporation”, 105)]
           2:  [Guid(“STRING DEL GUID”)]
           3:  internal sealed partial class AzManDslToolPackage : AzManDslToolPackageBase
           4:  {
           5:  }

         

        El ejemplo anterior muestra la registración de un PLK en un proyecto DSL pero esto aplica también para los paquetes de extensibilidad en general.
         
        Los parámetros del atributo “ProvideLoadKey” son:

        1. Versión mínima de Visual Studio, para la que aplica el paquete.
        2. Versión del proyecto.
        3. Nombre del producto.
        4. Nombre de la empresa que lo desarrolla.
        5. Identificador del String que contiene el PLK, en el archivo de recursos.

         

        La combinación de los primeros cuatro parámetros de “ProvideLoadKey” están codificados dentro del PLK y por lo tanto deben ser iguales a los declarados al obtener la clave.

        Antes de distribuir los archivos de instalación o siquiera intentar instalarlo en nuestras máquinas, cuestión que puede llevarnos varios valiosos minutos de nuestro tiempo, tenemos el beneficio de poder comprobar la correcta carga de la clave por parte del IDE. Solo hace falta ingresar en la sección de “Debug” dentro de las propiedades del proyecto e ingresar lo siguiente en Comand line arguments: “/rootsuffix Exp /noVSIP”. Por supuesto también deben configurar que al ejecutar el paquete se abra otra instancia de Visual Studio como se muestra en la siguiente imagen.

         

         

        Ilustración  2  Configuración del proyecto

         

        Luego si se ejecuta el proyecto se abrirá otra  instancia del IDE donde podemos probar nuestro paquete de extensibilidad. En caso de falla en la carga del PLK veremos un mensaje de error. Una vez efectuadas estas tareas y hecho el build del correspondiente proyecto de instalación pueden distribuir los archivos.

        Mantenimiento 

        Un tema muy importante que debemos tener en cuenta es que cuando hacemos algún mantenimiento al paquete de extensibilidad, ya sea que se corrijan funcionalidades o se agreguen nuevas y siempre y cuando cambiemos la versión (p.e. 1.0.0.0 a 1.0.0.1), seguramente vamos a tener que generar un nuevo instalador para desplegar la nueva versión. Atención! si se cambia la versión del producto se deberá actualizar la clave del paquete de extensibilidad (PLK) en el archivo de recursos correspondiente.

         Fuentes:

         

         

         

         

        Tags:

        Visual Studio

        Acerca de los Autores

        Este es el blog del equipo de VEMN SA 
        Presentaremos temas que nos parezcan de interés sobre tecnología .NET, Procesos y Metodologías y todo aquello relacionado con el proceso de desarrollo de Software

        Month List

        BlogRoll

        Download OPML file OPML