Pregunta

Estoy tratando de crear una aplicación web donde quiero ser capaz de plug-in de asambleas separadas.Estoy usando MVC vista previa de 4 combinado con la Unidad para la inyección de dependencia, el que yo uso para crear los controladores de mi plugin asambleas.Estoy usando Formularios web (aspx predeterminada) como mi punto de vista motor.

Si se desea utilizar un punto de vista, estoy atascado en el que están definidos en el proyecto básico, debido a la dinámica de la compilación de la ASPX parte.Estoy buscando una manera adecuada para adjuntar archivos ASPX en un montaje diferente, sin tener que ir a través de todo el paso de la implementación.Me estoy perdiendo algo que es obvio?O debo recurrir a la creación de mis puntos de vista mediante programación?


Actualización:He cambiado el aceptado respuesta.Aunque Dale la respuesta es muy completo, me fui para la solución con una diferente ruta de acceso virtual de proveedor.Funciona como un encanto, y sólo toma alrededor de 20 líneas de código totalmente, creo.

¿Fue útil?

Solución

Esencialmente, es el mismo problema que la gente tenía con WebForms y tratando de compilar sus UserControl ASCX archivos en un archivo DLL.He encontrado este http://www.codeproject.com/KB/aspnet/ASP2UserControlLibrary.aspx que podría funcionar para usted también.

Otros consejos

Me tomó demasiado tiempo para que todo esto funcione correctamente de los diferentes muestreos parciales, así que aquí está el código completo necesario para obtener la opinión de una de las Vistas de carpeta en una biblioteca compartida estructuran de la misma manera como regular las Vistas de carpeta pero con todo listo para construir como recursos incrustados.Sólo utilizará el archivo incrustado si la costumbre archivo no existe.

La primera línea de Application_Start:

HostingEnvironment.RegisterVirtualPathProvider(new EmbeddedViewPathProvider());

El VirtualPathProvider

   public class EmbeddedVirtualFile : VirtualFile
{
    public EmbeddedVirtualFile(string virtualPath)
        : base(virtualPath)
    {
    }

    internal static string GetResourceName(string virtualPath)
    {
        if (!virtualPath.Contains("/Views/"))
        {
            return null;
        }



        var resourcename = virtualPath
            .Substring(virtualPath.IndexOf("Views/"))
            .Replace("Views/", "OrangeGuava.Common.Views.")
            .Replace("/", ".");

        return resourcename;

    }


    public override Stream Open()
    {
        Assembly assembly = Assembly.GetExecutingAssembly();


        var resourcename = GetResourceName(this.VirtualPath);
        return assembly.GetManifestResourceStream(resourcename);
    }




}

public class EmbeddedViewPathProvider : VirtualPathProvider
{


    private bool ResourceFileExists(string virtualPath)
    {

        Assembly assembly = Assembly.GetExecutingAssembly();


        var resourcename = EmbeddedVirtualFile.GetResourceName(virtualPath);
        var result = resourcename != null && assembly.GetManifestResourceNames().Contains(resourcename);
        return result;
    }

    public override bool FileExists(string virtualPath)
    {
        return base.FileExists(virtualPath) || ResourceFileExists(virtualPath);
    }


    public override VirtualFile GetFile(string virtualPath)
    {

        if (!base.FileExists(virtualPath))
        {
            return new EmbeddedVirtualFile(virtualPath);
        }
        else
        {
            return base.GetFile(virtualPath);
        }

    }

}

El paso final para que funcione es que la raíz de la Web.Config debe contener la configuración adecuada para analizar establecimiento inflexible de tipos de vistas de MVC, como la que está en la carpeta vistas de no ser utilizados:

<pages
    validateRequest="false"
    pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
    pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
    userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
  <controls>
    <add assembly="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" namespace="System.Web.Mvc" tagPrefix="mvc" />
  </controls>
</pages>

Un par de pasos adicionales son necesarios para que funcione con el Mono.En primer lugar, usted necesita para implementar GetDirectory, ya que todos los archivos en la carpeta views se cargan cuando se inicia la aplicación, en lugar de como sea necesario:

public override VirtualDirectory GetDirectory(string virtualDir)
    {
        Log.LogInfo("GetDirectory - " + virtualDir);
        var b = base.GetDirectory(virtualDir);
        return new EmbeddedVirtualDirectory(virtualDir, b);
    }

public class EmbeddedVirtualDirectory : VirtualDirectory
{
    private VirtualDirectory FileDir { get; set; } 

    public EmbeddedVirtualDirectory(string virtualPath, VirtualDirectory filedir)
        : base(virtualPath)
    {
        FileDir = filedir;
    }

    public override System.Collections.IEnumerable Children
    {
        get { return FileDir.Children; }
    }

    public override System.Collections.IEnumerable Directories
    {
        get { return FileDir.Directories; }
    }

    public override System.Collections.IEnumerable Files
    {
        get {

            if (!VirtualPath.Contains("/Views/") || VirtualPath.EndsWith("/Views/"))
            {
                return FileDir.Files;
            }

            var fl = new List<VirtualFile>();

            foreach (VirtualFile f in FileDir.Files)
            {
                fl.Add(f);
            }


            var resourcename = VirtualPath.Substring(VirtualPath.IndexOf("Views/"))
.Replace("Views/", "OrangeGuava.Common.Views.")
.Replace("/", ".");

            Assembly assembly = Assembly.GetExecutingAssembly();

            var rfl = assembly.GetManifestResourceNames()
                .Where(s => s.StartsWith(resourcename))
                .Select(s => VirtualPath + s.Replace(resourcename, ""))
                .Select(s => new EmbeddedVirtualFile(s));
            fl.AddRange(rfl);

            return fl;
        }
    }
}

Finalmente, vistas inflexibles casi pero no del todo funcione a la perfección.El modelo será tratada como un tipo de objeto, así que para llegar fuerte a escribir de nuevo usted necesita para comenzar su puntos de vista compartidos con algo como

<% var Model2 = Model as IEnumerable<AppModel>;  %>
protected void Application_Start()
{
    WebFormViewEngine engine = new WebFormViewEngine();

    engine.ViewLocationFormats = new[] { "~/bin/Views/{1}/{0}.aspx", "~/Views/Shared/{0}.aspx" };
    engine.PartialViewLocationFormats = engine.ViewLocationFormats;

    ViewEngines.Engines.Clear();
    ViewEngines.Engines.Add(engine);

    RegisterRoutes(RouteTable.Routes);
}

Conjunto de la 'Copia a' salida de la propiedad de su vista a la Copia de siempre'

Una adición a todos los que todavía están buscando el santo grial:He llegado un poco más cerca de encontrarlo, si no estás demasiado apegado a la webforms viewengine.

Recientemente he probado la Chispa viewengine.Aparte de ser totalmente impresionante y yo no iría de nuevo a webforms incluso si yo estaba amenazadas, también proporciona muy buenos ganchos de la modularidad de una aplicación.El ejemplo de sus docs es el uso de Windsor como un contenedor de IoC, pero no puedo imaginar que es mucho más difícil si usted quiere tomar otro enfoque.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top