webpages visual studio net mvc instalar asp .net asp.net-mvc asp.net-mvc-4 assemblies

.net - visual - nuget system web webpages



404 en controladores en ensambles externos (3)

Se ve como este problema:

MVC utiliza el nombre de tipo calificado para ensamblaje del motor de vista para desambiguar las entradas de la memoria caché de vista desde diferentes motores de vista. Por lo tanto, no es posible tener más de un objeto PrecompiledMvcEngine (como cuando tiene vistas precompiladas en más de un ensamblaje) . El problema se puede resolver creando una clase derivada diferente de PrecompiledMvcEngine para cada ensamblaje. O creando una única clase derivada genérica parametrizada con algún tipo del ensamblaje.

El artículo está aquí .

Tengo problemas para resolver 404 respuestas en mi proyecto Asp.Net MVC 4. Está integrado en la orientación 4.5 de VS2012.

Tengo vista previa compiladas y controladores integrados en DLL independientes. Puedo cargar dinámicamente las DLL e inspeccionarlas desde mi proyecto principal, incluso invocar métodos sobre ellas; sin embargo, parece que MVC Framework no tiene conocimiento de los controladores. Estoy cerca aquí, pero falta algo.

Antecedentes en los Controladores y Vistas

Los controladores están integrados en un proyecto MVC independiente y heredan de Controller . Nada demasiado interesante pasando allí. Las vistas usan RazorGenerator y se convierten en clases que viven en el proyecto.

El resultado del proyecto es una DLL que contiene correctamente los controladores y las vistas.

Los DLL implementan una interfaz específica, la llamaremos IPlugin , en una clase separada (que no forma parte de un controlador) en la biblioteca.

Cargando los archivos DLL

Ejecutando como administrador en Visual Studio, compilo mi aplicación, alojada en IIS. Con el proyecto creado, dejo caer un archivo DLL de complemento en mi directorio "Complementos". Sin depuración (esto se vuelve importante más adelante), abro IE y navego al sitio. Tenga en cuenta que en este momento la aplicación se ha creado, pero nunca se ejecuta, por lo que los eventos de inicio se dispararán. Todo aquí sigue siendo constante si reciclo el grupo de aplicaciones.

Tengo una clase de Startup con dos métodos, PreStart y PostStart e invoco los métodos usando WebActivator.PreApplicationStartMethod y WebActivator.PostApplicationStartMethod respectivamente.

PreStart es donde hago lo siguiente:

  • Obtenga una lista de todas las DLL de complementos en mi directorio "Complementos"
  • Copie todos los complementos en AppDomain.CurrentDomain.DynamicDirectory
  • Cargue el tipo ... si contiene un IPlugin , entonces
    • Agregue el ensamblaje al BuildManager
    • Llame a algunos de los métodos en la clase que implementa IPlugin

En ''PostStart'' hago este bit de código (basado en el código de RazorGenerator.Mvc):

foreach (var assembly in Modules.Select(m=>m.Value)) { var engine = new PrecompiledMvcEngine(assembly) { UsePhysicalViewsIfNewer = HttpContext.Current.Request.IsLocal }; ViewEngines.Engines.Insert(0, engine); VirtualPathFactoryManager.RegisterVirtualPathFactory(engine); }

Modules en este contexto son un par clave / valor donde los valores son los conjuntos cargados. El propósito de este código es asegurarse de que MVC conozca las vistas al agregar un motor de vista para cada ensamblaje que sepa cómo resolver las vistas (esto es parte de RazorGenerator).

Cómo sé que estoy cerca (pero claramente sin cigarro)

IPlugin define un método llamado RegisterRoutes donde, lo adivinaste, las rutas se registrarán para aquellos que implementan la interfaz. Llamo a este método en PreStart y se agregan rutas. He verificado que existen en mi tabla de rutas. Por ejemplo, en una ruta definida en mi complemento, creada a través de la invocación dinámica del método durante el PreStart , veo algo así como un DataToken al examinar mis rutas:

Namespaces = Plugin.Name.Controllers

Entonces, la ruta está registrada, el ensamblaje está cargado, he verificado que la DLL se copió correctamente en el DynamicDirectory del AppDomain. Puedo invocar miembros de clases que se cargan dinámicamente en tiempo de ejecución. Pero cuando navego a la URL que coincide con la ruta , obtengo un 404 . Esta no es una vista "no se pudo ubicar" YSOD, es más parecido a no encontrar el controlador en absoluto.

Aquí está la parte que me confunde : si, en este momento, sin hacer nada, regreso a Visual Studio y presiono F5 ... todo funciona.

Es como si Visual Studio tomara conciencia del controlador de alguna manera que yo no puedo identificar, y MVC Framework está retomando el tema.

Finalmente, una pregunta

¿Qué me estoy perdiendo y cómo obtengo el MVC Framework para conocer mi controlador?

Y oye, en este punto, si todavía estás leyendo esto, gracias. :)



Resulta que esto es un error en Asp.Net.

Después de discutir el problema con Eilon Lipton del equipo de Asp.Net, y pensando que esto era algo malo en el MVC Framework, Eilon y un par de miembros del equipo analizaron las cosas y descubrieron que el error estaba en un nivel inferior en esta conversación: http: //aspnetwebstack.codeplex.com/discussions/403529

También sugirieron una solución alternativa que incluía otra llamada en BuildManager después de la llamada a AddReferencedAssembly , que implementé mediante el siguiente código:

// Add the plugin as a reference to the application BuildManager.AddReferencedAssembly(assembly); BuildManager.AddCompilationDependency(assembly.FullName);

Esto le permite agregar controladores adicionales / vistas compiladas al inicio en la etapa de inicio de la aplicación previa. Lo que estoy haciendo ahora es recorrer la lista de archivos DLL en mi directorio de complementos y enviarlos a BuildManager como se BuildManager arriba.

La única limitación aquí es que no puede eliminar ensamblajes ni borrar la memoria caché dinámicamente. La única forma que he encontrado de hacer esto es agregar un ensamblado desconocido anteriormente a los ensamblados a los que se hace referencia y a las dependencias de compilación. Estoy experimentando con la emisión dinámica de un nuevo ensamblaje durante la inicialización previa a la aplicación para poder siempre, de manera efectiva, borrar la caché y eliminar los complementos incluidos previamente fingiendo un nuevo ensamblaje.

Espero que esto ayude a alguien más allá.

Aclamaciones.