Dieser Artikel wurde maschinell übersetzt.

Orchard CMS

Orchard-Erweiterbarkeit

Bertrand Le Le

Der Code in Druckqualität herunterladen

Die meisten Web-Anwendungen haben eine Menge gemeinsam, aber zur gleichen Zeit weisen viele Unterschiede.Sie alle haben statische Seiten ("Bezeichnungen des Gebrauches," "Über uns" und So weiter).Sie stellen Inhalte in einem gemeinsamen Layout.Sie haben die Navigations-Menüs.Sie könnten Suche, Kommentare, BEWERTUNGEN und Integration von sozialen Netzen haben.Aber einige sind Blogs, einige Bücher zu verkaufen, einige Freunde in Verbindung bleiben und einige Hunderte von Tausenden von Verweis Artikel in Ihrem Lieblings-Technologien enthalten.

Ein Content Management System (CMS) zielt darauf ab, die häufig Stück während keine Auflagen auf die Art der Website gebaut.Es ist eine heikle Übung in Erweiterbarkeit.

Die Schöpfer der Orchard CMS (orchardproject.net) —, die enthält me — haben entschied sich für einen Ansatz, der massiv auf Zusammensetzung und Übereinkommen basiert.In diesem Artikel präsentiere ich einige Beispiele für einfache Erweiterungen an das System, das ein guter Ausgangspunkt für Ihre eigenen Module werden sollte.

Ein dynamisches Typsystem

Egal welche CMS Sie verwenden, um Ihre Website zu bauen, wird es eine zentrale Stelle Inhalte, die unter verschiedenen Namen geht.In Drupal es hat als Knoten bezeichnet und in Orchard, es ist ein Content-Element.Inhaltselemente sind Atome von Inhalten wie Blog-Posts, Seiten, Produkte, Widgets oder Status-Updates.Einige von ihnen eine URL entsprechen, und manche nicht.Ihre Schemas sind sehr unterschiedlich, aber was sie gemeinsam haben ist, dass sie die kleinsten Inhaltseinheiten auf der Website sind.Oder sind sie?

Aufteilung des Atoms

Als Entwickler ist unsere erste Reaktion Inhaltselemente als Instanzen von Klassen (Post, Seite, Produkt oder Widget), welche ist richtig in einem Ausmaß.(Felder, Eigenschaften und Methoden), Inhaltstypen (der "Klassen" von Content-Elementen) sind in der gleichen Weise, dass Klassen Mitglieder bestehen selbst zusammengesetzte Objekte.Statt einfache Eigenschaften mit Typen, die selbst Klassen aus, sind sie Inhalt Teile, die die Atome des Verhaltens Ihrer Inhalte sind aus.Dies ist eine wichtige Unterscheidung, die ich mit einem Beispiel illustrieren werde.

Eine Blog-Post besteht normalerweise aus einer URL, Titel, Datum, rich-Text-Körper, eine Liste von Tags und eine Liste der Benutzerkommentare.Keines der Teile ist spezifisch für einen Blog-Post.Was macht einen Blog-post ist der spezifischen Zusammensetzung der Teile, nicht nur einem der Teile.

Die meisten Blog-Posts haben Kommentare, aber Kommentare könnte auch in einer Commerce-Site verwendet werden, um Bewertungen zu implementieren.Ebenso sind Tags potentiell nützlicher als eine Möglichkeit, jedes Inhaltselement, nicht nur Blog-Posts zu klassifizieren.Der rich-Text-Körper eines Pfostens unterscheidet sich nicht aus dem Körper einer Seite.Die Liste geht weiter.Es sollte klar zu diesem Zeitpunkt sein, dass die Einheit der Verhalten auf einer Website kleiner als die Einheit von Inhalten ist.

Eine weitere Tatsache über CMS ist, dass Content-Typen sind nicht im Voraus festgesetzt.Blog-Posts verwendet, um einfache Text sein, aber sie bald wurde es viel mehr.Sie enthalten jetzt routinemäßig Videos, Podcasts oder Bild Galerien.Wenn Sie in Ihrem Blog über Ihre Reisen rund um die Welt, vielleicht Sie werden Geolocation auf Ihre Beiträge hinzufügen möchten.

Inhalt Teile wieder kommen zu Hilfe.Benötigen Sie eine Längen- und Breitengrad?Erweitern den Blog-Post-Typ einen Zuordnung Teil (wir haben mehrere verfügbar in unserer Galerie Modul: Gallery.orchardproject.NET).Es wird schnell offensichtlich, wenn man darüber nachdenkt, dass dieser Vorgang des Hinzufügens eines Teils auf einen vorhandenen Typ in den meisten Fällen durch den Eigentümer der Website, nicht von einem Entwickler durchgeführt wird.Daher sollten nicht möglich nur durch Hinzufügen einer komplexen Eigenschaft an eine Microsoft.NET Framework-Typ.Es muss metadatengesteuerte und zur Laufzeit geschehen, damit wir einen Admin-UI dafür erstellen können (siehe Abbildung 1).

The Orchard Content Type EditorAbbildung 1 die Orchard Content-Typ-Editor

Dies ist die erste Möglichkeit, Orchard zu erweitern: Sie können erstellen und Inhalte, die Typen aus der Admin-UI werden zu erweitern.Alles, was Sie, aus der Admin-UI tun können, können Sie natürlich von Code, wie dies tun:

item.Weld(part);

Dieser Code schweißt einen Teil auf ein Content-Element dynamisch. Das ist eine interessante Möglichkeit, wie sie Instanzen von Typen zur Laufzeit dynamisch erweitert werden können. In dynamischen Sprachen Dies nennt man eine Mischung-in, aber es ist ein Konzept, das fast ungehört in statisch typisierte Sprachen wie c# ist. Dies eröffnet neue Möglichkeiten, aber es ist nicht genau das gleiche, als was wir aus der Admin-UI Taten. Wir wollen auch in der Lage sein den Typ ein für allemal anstatt es für jede Instanz der Komponente hinzu, wie hier gezeigt:

ContentDefinitionManager.AlterTypeDefinition(
  "BlogPost", ctb => ctb.WithPart("MapPart")
);

Dies ist eigentlich genau wie der Blog-Post-Inhaltstyp in erster Linie definiert ist:

ContentDefinitionManager.AlterTypeDefinition("BlogPost",
  cfg => cfg
    .WithPart("BlogPostPart")
    .WithPart("CommonPart", p => p
      .WithSetting("CommonTypePartSettings.ShowCreatedUtcEditor", "true"))
      .WithPart("PublishLaterPart")
      .WithPart("RoutePart")
      .WithPart("BodyPart")
  );

Sie können in diesem Codeausschnitt feststellen, dass Tags und Kommentaren scheinen zu fehlen von Blog-Posts. Dies ist ein weiteres Beispiel sorgfältige Trennung von Bereichen. Das Blog-Modul weiß nichts von Tags und Kommentaren, eigentlich nicht mehr als die Tags und Kommentaren, dass Module über Blogs tun. Eine dritte Partei haftet für zusammen zu bringen.

Leckere Rezepte

Bei der Installation wird eine Rezept ausgeführt, die für diese Art von Aufgabe verantwortlich ist. Es ist eine XML-Beschreibung der ursprünglichen Konfiguration des Standortes. Obstgarten kommt mit drei Standard-Rezepte: Blog, Standard und Core. Der folgende Code zeigt den Teil der Blog-Rezept, das Blog-Posts die Tags und Kommentare hinzufügt:

<BlogPost ContentTypeSettings.Draftable="True" TypeIndexing.Included="true">
  <CommentsPart />
  <TagsPart />
  <LocalizationPart />
</BlogPost>

Ich habe bisher die verschiedenen Möglichkeiten gezeigt, in denen Inhalte Teile in Inhaltselementen bestehen können. Mein nächste Schritt wird sein, zu erklären, wie Sie Ihre eigenen Teile erstellen können.

Gebäude einen Teil

Zur Veranschaulichung den Prozess des Aufbaus eines neuen Teil werde ich auf das Beispiel der Meta-Funktion aus mein Vandelay Industrien Modul verlassen (Laden Sie es von bit.ly/u92283). Die Meta-Funktion fügt Schlüsselwörter und Beschreibung Eigenschaften für Search Engine Optimization (SEO) Zwecke (finden Sie unter Abbildung 2).

The SEO Meta Data Editor
Abbildung 2 die SEO Meta-Daten-Editor

Diese Eigenschaften werden in den Head-Abschnitt der Seite gerendert werden, wie standard Metatags, die Suchmaschinen zu verstehen:

    <meta content="Orchard is an open source Web CMS built on ASP.NET MVC."
      name="description" />
    <meta content="Orchard, CMS, Open source" name="keywords" />

Der Datensatz

Das erste Stück des Puzzles werden eine Beschreibung der Art und Weise, in der die Daten in der Datenbank beibehalten werden soll. Streng genommen, brauchen nicht alle Teile ein Datensatzes, weil nicht alle Teile ihre Daten in die Datenbank Orchard speichern, aber die meisten tun. Ein Datensatz ist nur ein reguläres Objekt:

public class MetaRecord : ContentPartRecord {
  public virtual string Keywords { get; set; }
  public virtual string Description { get; set; }
}

Die MetaRecord-Klasse wird von ContentPartRecord abgeleitet. Dies ist nicht unbedingt notwendig, aber es ist auf jeden Fall bequem, wie es einige der Grundstruktur aus dem Weg geht. Die Klasse verfügt über zwei Eigenschaften, Schlüsselwörter und Beschreibung. Diese Eigenschaften müssen virtuelle markiert werden, sodass Rahmen "Mischung-in kann" seine eigene Logik die konkrete Klasse erstellen, die zur Laufzeit verwendet wird.

Der Datensatz alleinige Verantwortung ist die Datenbank Persistenz, mit Hilfe einer Erklärung für den Speichermechanismus, der in der MetaHandler gefunden werden können:

public class MetaHandler : ContentHandler {
  public MetaHandler(
    IRepository<MetaRecord> repository) {
    Filters.Add(
      StorageFilter.For(repository));
  }
}

Der Speicher verfügt auch initialisiert werden. Frühe Versionen von Orchard waren das Datenbankschema aus der Rekord-Klasse ableiten, aber raten kann nur nehmen Sie so weit und dies wurde seitdem durch eine genauere Migration System in Änderungen am Schema explizit, definiert sind, wie in gezeigt ersetzt Abbildung 3.

Abbildung 3 definiert explizit Schemaänderungen

public class MetaMigrations : DataMigrationImpl {
  public int Create() {
    SchemaBuilder.CreateTable("MetaRecord",
      table => table
        .ContentPartRecord()
        .Column("Keywords", DbType.String)
        .Column("Description", DbType.String)
    );
    ContentDefinitionManager.AlterPartDefinition(
      "MetaPart", cfg => cfg.Attachable());
    return 1;
  }
}

Die MetaRecord-Tabelle wird mit einem Namen, den das System zuordnen kann durch Konvention zur MetaRecord-Klasse erstellt. Es hat die Systemspalten für inhaltliche Teil Hinzufügen eines Datensatzes durch den Aufruf der Methode ContentPartRecord plus die Schlüsselwörter und Beschreibung String-Spalten, die automatisch durch Übereinkommen in den entsprechenden Eigenschaften der die Benutzerdatensatz-Klasse zugeordnet wird.

Der zweite Teil der Migrationsmethode sagt, dass das neue Teil wird aus der Admin-UI auf alle vorhandenen Inhaltstypen anfügbare.

Die Create-Methode immer der Erstmigration darstellt und in der Regel liefert 1, der die Migration Anzahl. Die Konvention ist, dass in zukünftigen Versionen des Moduls, der Entwickler hinzufügen kann UpdateFromX Methoden, wobei x durch die Migration Anzahl ersetzt aus dem die Methode funktioniert. Die Methode sollte eine neue Migration Zahl, die entspricht der neuen Migration Anzahl des Schemas zurück. Dieses System erlaubt für reibungslose, unabhängige und flexible Upgrades aller Komponenten im System.

Um den tatsächlichen Teil darzustellen, ist eine separate Klasse verwendet, die ich jetzt betrachten.

Der Part-Klasse

Die Darstellung des Teils selbst ist eine weitere Klasse, die von ContentPart <TRecord>:

public class MetaPart : ContentPart<MetaRecord> {
  public string Keywords {
    get { return Record.Keywords; }
    set { Record.Keywords = value; }
  }
  public string Description {
    get { return Record.Description; }
    set { Record.Description = value; }
  }
}

Der Teil fungiert als Proxy für des Datensatzes Keywords und Beschreibung Eigenschaften aus Gefälligkeit, aber wenn es nicht, den Datensatz und seine Eigenschaften noch wäre durch die öffentliche Eigenschaft der Basisklasse ContentPart Datensatz vorhanden.

Code, der einen Verweis auf ein Content-Element, das der MetaPart Teil wird in der Lage, stark typisierten Zugriff auf die Keywords und Beschreibung Eigenschaften durch Aufrufen der As-Methode, die die analoge im Typsystem Orchard ein CLR ist geworfen werden Betrieb:

var metaKeywords = item.As<MetaPart>().Keywords;

Die Part-Klasse ist auch, wo Sie spezifische Verhalten der Teil Daten implementieren würde. Beispielsweise könnte ein zusammengesetzten Produkt verfügbar machen, Methoden oder Eigenschaften, um seine genusstauglichen zugreifen oder einen Gesamtpreis berechnen.

Verhalten, das bezieht sich auf eine Benutzerinteraktion (die Orchestrierung Code, der in einem regulären ASP würde.NET MVC-Anwendung in der Controller gefunden werden) ist eine andere Sache. Dies ist, wo Treiber kommen.

Der Treiber

Jeder Teil in ein Content-Element hat, erhalten Sie eine Gelegenheit zur Teilnahme an der Anforderungslebenszyklus und effektiv erledigen die Arbeit einer ASP.NET MVC-Controller, aber es muss, es zu tun auf der Skala des Teils Stelle von tuend es auf der Ebene der die vollständige Anforderung. Ein inhaltliche Teil Treiber spielt die Rolle der eine abgespeckte Controller. Es muss nicht den vollen Reichtum eines Controllers, es keine Zuordnung zu seiner Methoden von Routen gibt. Stattdessen besteht er Methoden für das Behandeln von klar definierten Ereignisse, z. B. Anzeige oder Editor. Ein Treiber ist nur eine Klasse, die von ContentPartDriver abgeleitet ist.

Die Display-Methode ist was aufgerufen wird, wenn Orchard den Teil in nur-Lese-Form dargestellt werden muss (siehe Abbildung 4).

Abbildung 4 des Fahrers Display-Methode bereitet das Rendering des Teils

protected override DriverResult Display(
  MetaPart part, string displayType, dynamic shapeHelper) {
  var resourceManager = _wca.GetContext().Resolve<IResourceManager>();
  if (!String.IsNullOrWhiteSpace(part.Description)) {
    resourceManager.SetMeta(new MetaEntry {
      Name = "description",
      Content = part.Description
    });
  }
  if (!String.IsNullOrWhiteSpace(part.Keywords)) {
    resourceManager.SetMeta(new MetaEntry {
      Name = "keywords",
      Content = part.Keywords
    });
  }
  return null;
}

Dieser Treiber ist in der Tat ein wenig Atypische, da die meisten Fahrer an einfache führen vor-Ort-Rendern (mehr dazu in Kürze), muß der Meta-Teil ihrer Metatags in den Kopf zu rendern. Head-Bereich eines HTML-Dokuments ist eine freigegebene Ressource so besondere Vorsichtsmaßnahmen notwendig sind. Obstgarten bietet APIs auf die freigegebenen Ressourcen, die ist, was Sie hier sehen: Ich werde über den Ressourcenmanager mit der Metatags festgelegt. Der Ressourcen-Manager kümmert sich um die Darstellung der tatsächlichen Tags.

Die Methode gibt null zurück, da gibt es nichts in diesem speziellen Szenario direktes Rendern. Die meisten Treiber Methoden werden stattdessen ein dynamisches Objekt bezeichnet eine Form, die ein Ansichtsmodell in ASP entspricht zurück.NET MVC. Ich komme zurück zu Shapes in einem Moment wenn die Zeit kommt, um sie in HTML-Code zu machen, aber für den Augenblick, es genügt zu sagen, sie sind sehr flexibel Objekte, wo Sie alles, was geht für die Vorlage relevant sein, der es, rendert halten können ohne eine besondere Klasse, erstellen, wie hier gezeigt:

protected override DriverResult Editor(MetaPart part, dynamic shapeHelper) {
  return ContentShape("Parts_Meta_Edit",
    () => shapeHelper.EditorTemplate(
      TemplateName: "Parts/Meta",
      Model: part,
      Prefix: Prefix));
}

Die Editor-Methode ist dafür verantwortlich, dass die Darstellung des Editors UI für das Teil. Es gibt in der Regel eine besondere Art von Form, die zum Erstellen von zusammengesetzten Ausgabe UIs geeignet ist.

Das letzte, was auf den Fahrer ist, dass die Methode, die behandelt wird Beiträge aus dem Editor:

protected override DriverResult Editor(MetaPart part,
  IUpdateModel updater, dynamic shapeHelper) {
  updater.TryUpdateModel(part, Prefix, null, null);
  return Editor(part, shapeHelper);
}

Der Code in dieser Methode ruft TryUpdateModel den Teil automatisch mit Daten zu aktualisieren, die zurückgesendet wurde. Nachdem diese Aufgabe abgeschlossen ist, wird der ersten Editor-Methode um die gleiche Form Editor zurückzugeben, die es produziert wurde.

Rendern von Formen

Durch Aufrufen von in allen Fahrern für alle Teile, Orchard ist in der Lage, eine Struktur von Formen zu erstellen — eine große Composite- und dynamische Ansicht-Modell für die gesamte Anforderung. Seine nächste Aufgabe besteht darin herauszufinden, wie man jeder Form in Vorlagen zu beheben, die in der Lage zu machen. Es tut sich also mit Blick auf den Namen jeder Form (Parts_Meta_Edit für die Methode Editor) und versucht, die Dateien an definierten Stellen des Systems, wie z. B. das aktuellen Themas und des Moduls zugeordnet Views Ordner. Dies ist ein wichtiger Erweiterungspunkt, da Sie die Standardwiedergabe von etwas im System überschreiben, indem nur eine Datei mit dem richtigen Namen in Ihrem lokalen Thema löschen können.

Im Ordner Views\EditorTemplates\Parts der mein Modul, ließ ich eine Datei namens Meta.cshtml (finden Sie unter Abbildung 5).

Abbildung 5 die Editor-Vorlage für die MetaPart

    @using Vandelay.Industries.Models
    @model MetaPart
    <fieldset>
      <legend>SEO Meta Data</legend>
      <div class="editor-label">
        @Html.LabelFor(model => model.Keywords)
      </div>
      <div class="editor-field">
        @Html.TextBoxFor(model => model.Keywords, new { @class = "large text" })
        @Html.ValidationMessageFor(model => model.Keywords)
      </div>
      <div class="editor-label">
        @Html.LabelFor(model => model.Description)
      </div>
      <div class="editor-field">
        @Html.TextAreaFor(model => model.Description)
        @Html.ValidationMessageFor(model => model.Description)
      </div>
    </fieldset>

Alles ist zufrieden

Bevor ich zu anderen Erweiterbarkeit Themen kommen, möchte ich erwähnen, dass, wenn Sie, das Inhaltselement Typsystem, Sie unter verstehen­stand das wichtigste Konzept in Orchard. Viele wichtige Elemente des Systems sind als Inhaltselemente definiert. Ein Benutzer ist beispielsweise ein Inhaltselement, das Profil-Module auf beliebige Eigenschaften hinzugefügt werden kann. Wir haben auch Widget Inhaltselemente, die in Zonen gerendert werden können, die ein Design definiert. Dies ist wie die Suche Formen, Blog-Archiv, Tag-Wolken und anderen Seitenleiste erhalten UI in Orchard erstellt. Aber die am meisten überraschende Verwendung von Content-Elementen möglicherweise die Website selbst. Websiteeinstellungen sind effektiv Inhaltselemente in Orchard, sehr viel Sinn macht, wenn Sie verstehen, wie Mandantenfähigkeit in Orchard verwaltet wird. Wenn Sie Ihre eigene Websiteeinstellungen hinzufügen möchten, alles, was Sie tun müssen, ist einen Teil der Websiteinhaltstyp hinzufügen und können Sie eine Admin Edition Benutzeroberfläche dafür nach genauer dieselben Schritte, die ich zuvor beschrieben. Ein einheitliches erweiterbare Content-Type-System ist ein extrem Reich Konzept.

Verpackung-Erweiterungen

Ich habe gezeigt, wie Sie Ihre eigenen Teile für Orchard zu bauen, und ich habe in die Konzepte der Module und Themen anspielte, ohne diese Begriffe definieren. Kurz gesagt, sind sie die Einheiten der Bereitstellung im System. Erweiterungen werden als Module verteilt, und das visuelle Erscheinungsbild wird als Themen verteilt.

Eine Thema ist in der Regel ein paar Bilder, Stylesheets und Vorlage überschreibt, verpackt in einem Verzeichnis unter das Themes-Verzeichnis. Es hat auch eine theme.txt Datei an der Wurzel zum Definieren von Metadaten wie z. B. der Autor des Themas manifestieren.

Ebenso ist ein Modul ein Verzeichnis unter dem Modules-Verzeichnis. Es ist auch eine ASP.NET MVC-Bereich, mit ein paar Drehungen. Beispielsweise ist eine zusätzliche module.txt manifest-Datei, die einige Metadaten für das Modul, z. B. der Autor, Website, Feature-Namen, Abhängigkeiten oder Versionsnummer deklariert.

Wird nur ein Teil einer größeren Website, muss ein Modul nice mit ein paar freigegebenen Ressourcen spielen. Beispielsweise müssen die Routen, die sie verwendet durch eine Klasse, die IRouteProvider definiert werden. Obstgarten bauen die komplette Routentabelle aus was von allen Modulen beigetragen wurde. Ebenso können Module zur Gebäude des Admin-Menüs durch Implementieren der INavigationProvider-Schnittstelle.

Interessant ist, ist nicht der Code für die Module in der Regel im kompilierten Binärdateien geliefert, (obwohl dies technisch möglich ist). Dies war eine bewusste Entscheidung, die wir zur Förderung Modul hackend, wo Sie beginnen aus einem Modul, die Sie herunterladen von der Galerie und optimieren, um Ihren individuellen Ansprüchen gerecht. Wird in der Lage, den Code für etwas ist eine der Stärken von PHP CMS wie Drupal oder WordPress, und wir wollten, dass dieselbe Art von Flexibilität im Obstgarten. Wenn Sie ein Modul herunterladen, Sie download Source-Code, und dieser Code Ruft dynamisch kompiliert. Wenn Sie eine Quelldatei ändern, die Änderung wird abgeholt und das Modul neu kompiliert wird.

Abhängigkeitsinjektion

So weit, ich habe konzentriert auf eine Art der Erweiterbarkeit, die Typsystem, da die Mehrheit der Orchard Module darstellt, aber es viele andere Erweiterungspunkte gibt — viel zu viele, in der Tat für mich um Sie hier aufzulisten. Ich möchte noch ein paar Dinge über die allgemeinen Grundsätze, die bei der Arbeit im gesamten Rahmen hinzufügen.

Eine wichtige Sache zu befindet sich in einem sehr modularen System lose Kopplung. In Orchard ist fast alles über Low-Level Sanitär ein Modul. Sogar Module werden von einem Modul verwaltet! Wenn Sie diese Module wie möglich unabhängig voneinander arbeiten möchten – wenn Sie eine Implementierung eines Features zu Swap mit einer anderen möchten — Sie können keine harte Abhängigkeiten.

Ein wichtiger Weg, um dieses Ziel zu erreichen soll Abhängigkeitsinjektion verwenden. Wenn Sie die Dienste von einer anderen Klasse verwenden müssen, instanziieren nicht nur es, die eine harte Abhängigkeit von dieser Klasse einrichten würden. Stattdessen Sie Spritzen, eine Schnittstelle, die diese Klasse als Konstruktorparameter implementiert (siehe Abbildung 6).

Abbildung 6 Injektion von Abhängigkeiten durch Konstruktorparameter

private readonly IRepository<ContentTagRecord> _contentTagRepository;
private readonly IContentManager _contentManager;
private readonly ICacheManager _cacheManager;
private readonly ISignals _signals;
public TagCloudService(
  IRepository<ContentTagRecord> contentTagRepository,
  IContentManager contentManager,
  ICacheManager cacheManager,
  ISignals signals)
  _contentTagRepository = contentTagRepository;
  _contentManager = contentManager;
  _cacheManager = cacheManager;
  _signals = signals;
}

Auf diese Weise ist Ihre Abhängigkeit auf die Schnittstelle der Klasse und nicht die Implementierung kann ausgetauscht werden, ohne den Code ändern. Die spezifische Implementierung der Schnittstelle, die injiziert Ruft ist nicht mehr die Entscheidung des Verbrauchers von der Schnittstelle. Kontrolle ist hier, und es ist der Rahmen, der die Entscheidung trifft.

Natürlich ist dies nicht beschränkt auf die Schnittstellen, die Orchard definiert. Jedes Modul kann stellen eigene Erweiterbarkeitspunkte bereit, indem nur deklariert eine Schnittstelle, die von IDependency abgeleitet ist. Es ist wirklich so einfach.

Einige andere Erweiterungspunkte

Ich habe hier nur die Oberfläche der Erweiterbarkeit verkratzt. Es gibt viele Schnittstellen, die in Orchard verwendet werden können, um das System auf kreative Weise zu erweitern. Man könnte sogar sagen, dass Orchard im wesentlichen nichts anderes als eine Erweiterbarkeit-Engine ist. Alle Stücke in das System sind Swap-fähige und erweiterbare.

Bevor ich dieses Artikels schließe, werde ich einige der nützlichsten Schnittstellen im System erwähnen, die Sie auschecken möchten. Ich haben nicht annähernd genug Zimmer hier in diese in die Tiefe, gehen aber ich kann Ihnen Zeiger, und Sie können in den Code gehen und folgen der Verwendung der Schnittstellen. Dies ist wirklich eine großartige Möglichkeit zu lernen, durch die Art und Weise.

  • IWorkContextAccessor kann Ihren Code auf den Arbeitskontext für die aktuelle Anforderung. Die Arbeitskontext wiederum ermöglicht den Zugriff auf HttpContext, aktuellen Layout, Site-Konfiguration, Benutzer, Thema und Kultur. Es bietet auch eine Implementierung einer Schnittstelle aus diesen Orten zu erhalten, wo Sie Abhängigkeitsinjektion tun können oder müssen Sie es erst nach Bau verzögern.
  • IContentManager bietet alles, was Sie müssen Abfragen und Verwalten von Content-Elementen.
  • IRepository <T> ermöglicht den Zugriff auf niedrigerer Ebene Datenzugriffsmethoden für die damalige Zeit, wenn IContentManager nicht genug ist.
  • IShapeTableProvider ermöglicht eine Schiffsladung von on-the-Fly Form Manipulation Szenarien. Grundsätzlich Sie hook up auf Ereignisse zu Formen, und aus ihnen können Sie alternative Formen in bestimmten Situationen verwendet werden, Formen verwandeln, Mitglieder hinzufügen, verschieben Sie sie, um in das Layout und so weiter.
  • IBackgroundTask, IScheduledTask und IScheduled­TaskHandler sind Schnittstellen zu verwenden, wenn Sie verzögerte oder wiederholte Aufgaben im Hintergrund ausgeführt werden müssen.
  • IPermissionsProvider ermöglicht Ihrer Module, ihre eigenen Berechtigungen verfügbar zu machen.

Weitere Informationen

Orchard ist ein Kraftpaket Erweiterbarkeit und präsentiert alles, was, die es zu in diesem begrenzten Raum zu bieten hat, ist eine Herausforderung. Meine Hoffnung ist, dass ich Sie den Willen gab, erfahren mehr über es und Tauchen Sie tief hinein. Wir haben eine freundliche und lebendige Gemeinschaft auf orchard.codeplex.com/discussions , die gerne begleiten Sie und beantworten Ihre Fragen. Mit so viel zu implementieren, und so viele Ideen zu erforschen ist hier eine große Chance, einen bedeutenden Beitrag leisten.

Bertrand Le Roy begann seine professionelle Entwickler Karriere 1982 als er seine erste Video-Spiel veröffentlichte. Er erschien im Jahr 2002 was wahrscheinlich die ersten CMS auf ASP.NET. Ein Jahr später wurde er von der Microsoft ASP eingestellt.NET-Team und zog in die USA. Er arbeitete an ASP.NET Versionen 2.0 bis 4 und ASP.NET AJAX; dazu beigetragen, dass jQuery einen offiziellen Bestandteil der.NET-Entwicklers Werkzeugtruhe; und stellt Microsoft im OpenAjax Alliance Steering Committee.

Dank der folgenden technischen Experten für die Überprüfung dieses Artikels: Sebastien Ros