lunes, 5 de marzo de 2012

Características: receivers y scopes

A raíz de una consulta en los foros de SharePoint he pensado que valía la pena dedicar un rato a explicar un concepto que, pese a ser aparentemente simple, suele causar más de un problema a todo aquel que trabaja con SharePoint. La problemática radica en el concepto feature scope o ámbito de la característica. Voy a intentar introducir primeramente el tema.

Sabréis que SharePoint, en su versión 2007, introdujo el tema de característica o feature que podría definirse como elemento mínimo de despliegue de funcionalidad y que, en ocasiones, tienen asociado un receiver que es un código manejado que se ejecuta cuando la característica se instala, se activa, se desactiva y se desinstala. Bien, resulta que las características pueden tener cuatro ámbitos diferentes en función del elemento o elementos a desplegar: granja, aplicación web, colección de sitios y sitio. Cuando no hay receiver el asunto suele ser bastante simple ya que suele haber una única posibilidad a la hora de seleccionar el ámbito. Si, por la razón que sea, existe más de una posibilidad tampoco es problema, porque en cualquiera de esas posibilidades el elemento se desplegará correctamente o saltará un error indicando que la característica no está bien definida.

El problema viene cuando tenemos un receiver el código del cual estamos desarrollando nosotros, y se debe al hecho que la característica se puede definir con cualquier ámbito y somos nosotros los que tenemos que actuar en consecuencia para que nuestro código funcione de manera adecuada. Voy a poner un ejemplo muy extremo para que veáis el tipo de cosas que se pueden hacer porque el sistema lo permite, pero que no deberían hacerse salvo que sepamos exactamente por qué lo estamos haciendo de esa manera.

Digamos que quiero desplegar una característica que, cuando se active, acceda al servicio de perfiles de usuario y haga un tratamiento sobre cada uno de los perfiles. Al estar tratando sobre una aplicación de servicio, lo lógico sería que su ámbito fuera aplicación web o granja (la decisión depende de la aplicación de servicio pero abordar este asunto está fuera del alcance de este artículo). Sin embargo, yo puedo decidir crear mi característica con ámbito de sitio y, en el código de activación hacer lo siguiente:

var web = properties.Feature.Parent as SPWeb;
var webApplication = web.Site.WebApplication;

Ahora tendría acceso al objeto SPWebApplication correspondiente al sitio donde estoy activando la característica. Esto no debería ser un problema pero, a la hora de la verdad, si tienes un código que está haciendo algo relacionado con el objeto SPWebApplication es probable que lo acabes utilizando en el futuro en otro proyecto y, en general, te encontrarás con un problema relacionado porque en ese nuevo proyecto, habrás pensado de otra manera, y esta vez tu característica la habrás definido con alcance aplicación web y el código anterior compilará, funcionará aparentemente, pero dará un error de NullReferenceException porque la primera línea de arriba devolverá un objeto nulo.

Si queréis dejar vuestro receiver totalmente protegido de cara a futuras reutilizaciones deberíais tratar las cuatro posibilidades que se os pueden llegar a dar. La idea sería obtener el tipo del objeto properties.Feature.Parent del ejemplo anterior y, en base al resultado, ejecutar un código u otro, o incluso devolver un error controlado y evitar el NullReferenceException que, si bien da toda la información, no va a ayudar a aquella persona que quiere reutilizar vuestro receiver.

En cualquier caso es importante intentar siempre escoger el ámbito más correcto para vuestra característica y, en ese caso, dependerá del código que vayáis a escribir. Si veis que vuestro código hace algo como lo de arriba, muy probablemente hayáis decidido mal y el ámbito correcto debería ser aplicación web. La idea es plantearse cual va a ser el objeto que va a recibir tratamiento por parte de nuestro código y establecerlo como el Parent de la característica a crear.

0 comentarios: