Saltar al contenido

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript... y lo que venga ;)

18 años online

el blog de José M. Aguilar

Inicio El autor Contactar

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web
ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript...

¡Microsoft MVP!
martes, 22 de noviembre de 2022
Blazor

Hoy va un post cortito, pero que puede venir bien a alguien que esté intentando "trocear" su aplicación en distintos proyectos y se haya encontrado con este problema.

Echemos un vistazo al contenido típico del archivo App.razor de una aplicación Blazor (Server o WebAssembly, da lo mismo):

<Router AppAssembly="@typeof(Program).Assembly">
    ...
</Router>

Resulta que el componente Router escanea durante su inicialización el ensamblado que hayamos indicado en su atributo AppAssembly, por defecto el ensamblado actual, en busca de componentes que:

  • Hayan definido sus rutas mediante directivas @page de Razor,
  • o bien, que tengan su ruta especificada con atributos [Route]

En cualquiera de los casos, los componentes localizados son añadidos a la tabla de rutas y, por tanto, será posible navegar hacia ellos modificando la ruta del navegador, ya sea programáticamente (usando el servicio NavigationManager) o bien mediante la pulsación de enlaces o modificación directa en la barra de direcciones.

Hasta aquí, todo correcto. El problema viene cuando las páginas que queremos añadir a la tabla de rutas no están en el ensamblado actual, o se encuentran repartidas en varios ensamblados distintos, por ejemplo en:

  • Otros proyectos de la solución
  • Ensamblados externos, referenciados directamente
  • Paquetes NuGet instalados en el proyecto

¿La solución?

Pues es bien sencilla, y consiste únicamente en utilizar el atributo AdditionalAssemblies para indicar un array de ensamblados adicionales donde debe realizarse la búsqueda, por ejemplo así:

<Router AppAssembly="@typeof(Program).Assembly"
        AdditionalAssemblies="@additionalAssemblies">
    ...
</Router>

@code {
    static Assembly[] additionalAssemblies = new[]
    {
        typeof(ExternalType1).Assembly,
        typeof(ExternalType2).Assembly,
    };
}

En este caso, además del ensamblado actual (donde se encuentra definida la clase Program), se añadirían al routing las páginas presentes en los ensamblados donde hayan sido definidos los tipos ExternalType1 y ExternalType2.

Espero que os sea de utilidad :)

Publicado en Variable not found.

4 Comentarios:

Adrian dijo...

Hola José.
Me estoy iniciando en Blazor. Si tengo una Solución llamada "Demo", con dos proyectos, y quiero navegar desde la página "Index" del proyecto "Uno" a otra página "Index" del proyecto "Dos", dentro de la misma solución, ¿Cómo sería el App.razor ?.
Saludos

José María Aguilar dijo...

Hola, Adrián!

No tengo claro el escenario que quieres montar. Si se trata de dos proyectos que lanzas de forma independiente y cada uno estará funcionando en su propio host/puerto, la navegación será la habitual, con un hipervínculo completo (protocolo+host+puerto+ruta) hacia la página de destino.

En cambio, si hablamos de que uno de los dos es el proyecto principal (el que arranca la aplicación), ya es distinto. Suponiendo que el primer proyecto se llama Proyecto1 y el otro Proyecto2:

- Desde Proyecto1 deberías añadir una referencia a Proyecto2, para que sus componentes estén disponibles.
- Las rutas de las páginas de ambos proyectos deben ser distintas, porque en caso contrario aparecerá un error de ambigüedad (por ejemplo, no puede ser que existan dos páginas Index con ruta "/").
- El App.razor de Proyecto1, suponiendo que la página de destino está en Proyecto2>Pages/Index.razor, sería algo como:

<Router AppAssembly="@typeof(App).Assembly" AdditionalAssemblies="new []{ typeof(Proyecto2.Pages.Index).Assembly }" >
...
</Router>

Adrian dijo...

Hola José!
Hablaba de que uno de los proyectos es el principal (el que arranca la aplicación).
Seguí los pasos que tu describiste y funciona de maravillas!!
Gracias José por tus enseñanzas!!

Saludos

Adrián


José María Aguilar dijo...

Genial! Muchas gracias por comentar!