Frage

Ich bin derzeit mit dynamisch belasteten Bereichen mit ASP.NET MVC 3 RC experimentieren. Ich habe es in vielen Orten geschrieben gesehen, dass dies nicht, welche Bereiche bestimmt sind für und (zumindest Pre-MVC 2) nicht möglich, sagt hier zum Beispiel.

Aber immer noch! Es sollte möglich sein, sie zur Arbeit zu kommen, nicht wahr? Ich habe eine Lösung geschaffen, ein MVC 3-Projekt, fügte eine Fläche und einige Inhalte hinzugefügt. Alle gut funktioniert. Jetzt habe ich ein neues Klassenbibliotheksprojekt (in der gleichen Lösung), einen Verweis auf mich aus dem MVC-Projekt hinzugefügt, und begann, in die Bibliothek über die flächenbezogenen Teile bewegen. Geändert, um die Ausgabe-Verzeichnis des Bibliothek-Projekt in den Bereich-Ordner des MVC-Projekt, und sorgte dafür, dass die Ansichten und ihre web.config kopiert werden an den Ausgabeordner.

Nach der Lektüre so viel darüber, wie Sie keine externen Bereiche haben könnten, es war ein wenig überraschend, dass dies funktioniert. Kein Problem bei allen wirklich! Das Problem beginnt, wenn ich den Bezug zwischen den Projekten entfernen und stattdessen die Bibliothek in Code laden. (Vor AreaRegistration.RegisterAllAreas() Aufruf.) Nun ist es nicht funktioniert. Bei allen.

Ich habe Stocher schon ein wenig in der Quelle für MVC 3, und das Problem scheint mit BuildManager.GetReferencedAssemblies() die die Baugruppen Look für Implementierungen von AreaRegistration zu bekommen verwendet wird.

Nun, ich bin nicht 100% sicher darüber, aber es scheint, als ob diese Methode bei Baugruppen sieht nur die zum Zeitpunkt der Kompilierung, kann jemand bestätigen present / verwiesen waren, wenn dies in der Tat so?

Ich habe durch diese debuggt, und dieser Methode-Aufruf ist in der Tat nicht die Baugruppe mich vor dem Aufruf geladen, nur um es zu finden. Es könnte wegen etwas anderes sein, dass ich vielleicht .. Irgendwelche Ideen verpasst haben?

War es hilfreich?

Lösung

Die Art und Weise der Dinge Arbeit ist ein wenig kompliziert.

GetReferencedAssemblies enthält referenzierten Assemblys, nicht geladen Baugruppen. Dazu gehören:

  • alle referenzierten Assemblys in Ihrer Anwendung web.config (wie System.Web.Mvc)
  • alles von der Wurzel web.config geerbt, die Dinge wie System, System.Web und andere beinhaltet, dass Sie nicht selbst hinzufügen müssen. (Sie können in der Liste einen Blick hier: C:\Windows\Microsoft.Net\Framework\v4.0.30319\web.config).
    Es enthält auch einen speziellen * Artikel, die :
  • enthält alles, was in bin Ihrer Website Ordner

So, jetzt die App v1 (alles in einer einzigen App) nehmen. Alles funktioniert, weil der Anwendungscode in den Papierkorb-Ordner erstellt wird, die automatisch aufgenommen wird. Auch alle Bereichsansichten usw. sind in der Anwendung selbst, so dass sie zugänglich sind.

Jetzt in app v2 (anderes Projekt mit einer proj-to-proj Referenz und eine benutzerdefinierte Build-Aufgabe, die Kopien, die Ansichten an die richtigen Stelle in der Haupt app) alles noch funktioniert, weil standardmäßig eine proj-to-proj Referenzen bedeuten, dass die Klassenbibliothek binär zu Ihren App Binärordner kopiert wird. So durch die oben genannten Regeln, wird der Ortsvorwahl noch richtig geladen. Die Tatsache, dass Sie die Bibliothek des Ausgabepfad festgelegt haben einig Standorte innerhalb Ihrer App-Bereiche werden Ordner nicht wirklich einen Unterschied machen -. Sie nur mit zwei Kopien der binären am Ende

Jetzt in app v3 (keine proj-proj ref, Bereich Bibliothek Assembly geladen manuell) Ihre Bibliothek wird Baugruppe zu spät geladen. Mit der Zeit läuft Ihr Code den Satz von referenzierten Baugruppen bereits gesperrt und kann nicht mehr geändert werden kann.

Es gibt einen Weg, um Code auszuführen, und fügen Sie Elemente in der Liste der registrierten Baugruppen: Sie können es tun, um die AddReferencedAssembly Methode, die em <> muss aufgerufen wird, von einem PreApplicationStartMethodAttribute Methode .

Natürlich müssen Sie noch behandeln, wie Sie die Ansicht Dateien verwalten. Die Art und Weise Sie derzeit haben es eingerichtet ist so ziemlich das gleiche wie die Ansichten in der Hauptanwendung, die (da sie effektiv in die richtige Stelle kopiert werden).

Andere Tipps

1 - Seperate Sie Mvc Bereiche in differ Mvc Projekte in ihre eigenen separaten Baugruppen erstellt werden

2 - Fügen Sie diese auf Ihrem AssemblyInfo.cs Klasse, eine Methode aufrufen, wenn die Anwendung geladen wird

[assembly: PreApplicationStartMethod(typeof(PluginAreaBootstrapper), "Init")]

3 - Hier ist, was die Init-Methode aussieht, wenn es während der Belastung

aufgerufen werden
public class PluginAreaBootstrapper
{
    public static readonly List<Assembly> PluginAssemblies = new List<Assembly>();

    public static List<string> PluginNames()
    {
        return PluginAssemblies.Select(
            pluginAssembly => pluginAssembly.GetName().Name)
            .ToList();
    }

    public static void Init()
    {
        var fullPluginPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Areas");

        foreach (var file in Directory.EnumerateFiles(fullPluginPath, "*Plugin*.dll"))
            PluginAssemblies.Add(Assembly.LoadFile(file));

        PluginAssemblies.ForEach(BuildManager.AddReferencedAssembly);
    }
}

4 - Fügen Sie eine benutzerdefinierte RazorViewEngine

public class PluginRazorViewEngine : RazorViewEngine
{
    public PluginRazorViewEngine()
    {
        AreaMasterLocationFormats = new[]
        {
            "~/Areas/{2}/Views/{1}/{0}.cshtml",
            "~/Areas/{2}/Views/{1}/{0}.vbhtml",
            "~/Areas/{2}/Views/Shared/{0}.cshtml",
            "~/Areas/{2}/Views/Shared/{0}.vbhtml"
        };

        AreaPartialViewLocationFormats = new[]
        {
            "~/Areas/{2}/Views/{1}/{0}.cshtml",
            "~/Areas/{2}/Views/{1}/{0}.vbhtml",
            "~/Areas/{2}/Views/Shared/{0}.cshtml",
            "~/Areas/{2}/Views/Shared/{0}.vbhtml"
        };

        var areaViewAndPartialViewLocationFormats = new List<string>
        {
            "~/Areas/{2}/Views/{1}/{0}.cshtml",
            "~/Areas/{2}/Views/{1}/{0}.vbhtml",
            "~/Areas/{2}/Views/Shared/{0}.cshtml",
            "~/Areas/{2}/Views/Shared/{0}.vbhtml"
        };

        var partialViewLocationFormats = new List<string>
        {
            "~/Views/{1}/{0}.cshtml",
            "~/Views/{1}/{0}.vbhtml",
            "~/Views/Shared/{0}.cshtml",
            "~/Views/Shared/{0}.vbhtml"
        };

        var masterLocationFormats = new List<string>
        {
            "~/Views/{1}/{0}.cshtml",
            "~/Views/{1}/{0}.vbhtml",
            "~/Views/Shared/{0}.cshtml",
            "~/Views/Shared/{0}.vbhtml"
        };

        foreach (var plugin in PluginAreaBootstrapper.PluginNames())
        {
            masterLocationFormats.Add(
                "~/Areas/" + plugin + "/Views/{1}/{0}.cshtml");
            masterLocationFormats.Add(
                "~/Areas/" + plugin + "/Views/{1}/{0}.vbhtml");
            masterLocationFormats.Add(
                "~/Areas/" + plugin + "/Views/Shared/{1}/{0}.cshtml");
            masterLocationFormats.Add(
                "~/Areas/" + plugin + "/Views/Shared/{1}/{0}.vbhtml");

            partialViewLocationFormats.Add(
                "~/Areas/" + plugin + "/Views/{1}/{0}.cshtml");
            partialViewLocationFormats.Add(
                "~/Areas/" + plugin + "/Views/{1}/{0}.vbhtml");
            partialViewLocationFormats.Add(
                "~/Areas/" + plugin + "/Views/Shared/{0}.cshtml");
            partialViewLocationFormats.Add(
                "~/Areas/" + plugin + "/Views/Shared/{0}.vbhtml");

            areaViewAndPartialViewLocationFormats.Add(
                "~/Areas/" + plugin + "/Views/{1}/{0}.cshtml");
            areaViewAndPartialViewLocationFormats.Add(
                "~/Areas/" + plugin + "/Views/{1}/{0}.vbhtml");
            areaViewAndPartialViewLocationFormats.Add(
                "~/Areas/" + plugin + "/Areas/{2}/Views/{1}/{0}.cshtml");
            areaViewAndPartialViewLocationFormats.Add(
                "~/Areas/" + plugin + "/Areas/{2}/Views/{1}/{0}.vbhtml");
            areaViewAndPartialViewLocationFormats.Add(
                "~/Areas/" + plugin + "/Areas/{2}/Views/Shared/{0}.cshtml");
            areaViewAndPartialViewLocationFormats.Add(
                "~/Areas/" + plugin + "/Areas/{2}/Views/Shared/{0}.vbhtml");
        }

        ViewLocationFormats = partialViewLocationFormats.ToArray();
        MasterLocationFormats = masterLocationFormats.ToArray();
        PartialViewLocationFormats = partialViewLocationFormats.ToArray();
        AreaPartialViewLocationFormats = areaViewAndPartialViewLocationFormats.ToArray();
        AreaViewLocationFormats = areaViewAndPartialViewLocationFormats.ToArray();
    }
}

5 - Registrieren Sie Ihre Bereiche von Ihrer verschiedenen Mvc (Region) Projekte

namespace MvcApplication8.Web.MyPlugin1
{
    public class MyPlugin1AreaRegistration : AreaRegistration
    {
        public override string AreaName
        {
            get { return "MyPlugin1"; }
        }

        public override void RegisterArea(AreaRegistrationContext context)
        {
            context.MapRoute(
                "MyPlugin1_default",
                "MyPlugin1/{controller}/{action}/{id}",
                new {action = "Index", id = UrlParameter.Optional}
                );
        }
    }
}

Sourcecode und weitere Referenzen finden Sie finden Sie hier: http://blog.longle.io/2012/03/29/building-a-composite-mvc3-application-with-pluggable-areas

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top