Sollten die Ordner in einer Lösung mit dem Namespace übereinstimmen?

129

Sollten die Ordner in einer Lösung mit dem Namespace übereinstimmen?

In einem meiner Teamprojekte haben wir eine Klassenbibliothek mit vielen Unterordnern im Projekt.

Projektname und Namensraum: MyCompany.Project.Section.

Innerhalb dieses Projekts gibt es mehrere Ordner, die dem Namespace-Abschnitt entsprechen:

  • Der Ordner Vehiclesenthält Klassen im MyCompany.Project.Section.VehiclesNamespace
  • Der Ordner Clothingenthält Klassen im MyCompany.Project.Section.ClothingNamespace
  • etc.

In demselben Projekt befindet sich ein weiterer Rogue-Ordner

  • Der Ordner BusinessObjectsenthält Klassen im MyCompany.Project.SectionNamespace

Es gibt einige Fälle wie diesen, in denen Ordner aus "organisatorischen Gründen" erstellt werden.

Meine Frage ist: Was ist der Standard? In Klassenbibliotheken stimmen die Ordner normalerweise mit der Namespace-Struktur überein oder handelt es sich um eine gemischte Tasche?

Marius Bancila
quelle
9
Hinweis: ReSharper beschwert sich, wenn Namespaces nicht mit der Ordnerhierarchie übereinstimmen.
Fred

Antworten:

76

Beachten Sie außerdem, dass wenn Sie die integrierten Vorlagen zum Hinzufügen von Klassen zu einem Ordner verwenden, diese standardmäßig in einem Namespace abgelegt werden, der die Ordnerhierarchie widerspiegelt.

Die Klassen werden leichter zu finden sein und das allein sollte Grund genug sein.

Die Regeln, denen wir folgen, sind:

  • Der Projekt- / Assembly-Name ist bis auf die DLL-Endung mit dem Root-Namespace identisch
  • Die einzige Ausnahme von der obigen Regel ist ein Projekt mit einer .Core-Endung. Der .Core wird entfernt
  • Ordner entsprechen Namespaces
  • Ein Typ pro Datei (Klasse, Struktur, Aufzählung, Delegat usw.) erleichtert das Auffinden der richtigen Datei
Lasse V. Karlsen
quelle
1
+1 für "Die einzige Ausnahme von der obigen Regel ist ein Projekt mit einer .Core-Endung, der .Core wird entfernt" . Ich habe eine MyProject.Core.dllVersammlung und alle Klassen beginnen mit MyProject.Core. Das Entfernen des .CoreSuffixes ist viel sinnvoller.
Luiz Damim
2
Eine weitere Ausnahme, die ich hinzufügen könnte, sind Ausnahmen. Ausnahmen werden bereits mit 'Ausnahme' versehen, sodass ein zusätzlicher Namespace redundant ist. Es kann auch chaotisch werden, einen Teil des Namespace mit dem Wort Exception zu haben (kann zu einer Verwirrung von System.Exception führen). Das Organisieren in Ordnern ist jedoch sehr hilfreich.
Phillipwei
53

Nein.

Ich habe beide Methoden bei kleinen und großen Projekten ausprobiert, sowohl mit Single (mir) als auch mit einem Entwicklerteam.

Ich fand, dass der einfachste und produktivste Weg darin bestand, einen einzelnen Namespace pro Projekt zu haben, und alle Klassen gehen in diesen Namespace. Sie können die Klassendateien dann in beliebigen Projektordnern ablegen. Das Hinzufügen von Anweisungen am Anfang von Dateien ist kein Problem, da nur ein einziger Namespace vorhanden ist.

Es ist wichtig, Quelldateien in Ordnern zu organisieren, und meiner Meinung nach sollten alle Ordner dafür verwendet werden. Das Erfordernis, dass diese Ordner auch Namespaces zugeordnet werden, ist unnötig, schafft mehr Arbeit und ich fand, dass dies tatsächlich schädlich für die Organisation ist, da die zusätzliche Belastung die Desorganisation fördert.

Nehmen Sie zum Beispiel diese FxCop-Warnung:

CA1020: Vermeiden Sie Namespaces mit wenigen Typen.
Ursache: Ein anderer Namespace als der globale Namespace enthält weniger als fünf Typen. Https://msdn.microsoft.com/en-gb/library/ms182130.aspx

Diese Warnung empfiehlt das Speichern neuer Dateien in einem generischen Project.General-Ordner oder sogar im Projektstamm, bis Sie vier ähnliche Klassen haben, um das Erstellen eines neuen Ordners zu rechtfertigen. Wird das jemals passieren?

Dateien finden

Die akzeptierte Antwort lautet: "Die Klassen werden leichter zu finden sein und das allein sollte Grund genug sein."

Ich vermute, die Antwort bezieht sich auf mehrere Namespaces in einem Projekt, die nicht der Ordnerstruktur zugeordnet sind, und nicht darauf, was ich vorschlage, welches ein Projekt mit einem einzelnen Namespace ist.

In jedem Fall können Sie anhand des Namespace nicht feststellen, in welchem ​​Ordner sich eine Klassendatei befindet. Sie können sie jedoch mithilfe von Gehe zu Definition oder des Explorationsfelds für die Suchlösung in Visual Studio finden. Auch das ist meiner Meinung nach kein großes Problem. Ich verbringe nicht einmal 0,1% meiner Entwicklungszeit mit dem Problem, Dateien zu finden, um eine Optimierung zu rechtfertigen.

Namenskonflikte

Wenn Sie mehrere Namespaces erstellen, kann das Projekt zwei Klassen mit demselben Namen haben. Aber ist das wirklich eine gute Sache? Ist es vielleicht einfacher, dies nicht zuzulassen? Wenn Sie zwei Klassen mit demselben Namen zulassen, entsteht eine komplexere Situation, in der 90% der Zeit bestimmte Dinge funktionieren und Sie plötzlich feststellen, dass Sie einen Sonderfall haben. Angenommen, Sie haben zwei Rechteckklassen in separaten Namespaces definiert:

  • Klasse Project1.Image.Rectangle
  • Klasse Project1.Window.Rectangle

Es ist möglich, auf ein Problem zu stoßen, dass eine Quelldatei beide Namespaces enthalten muss. Jetzt müssen Sie den vollständigen Namespace überall in dieser Datei ausschreiben:

var rectangle = new Project1.Window.Rectangle();

Oder mit einer bösen Anweisung herumspielen:

using Rectangle = Project1.Window.Rectangle;

Mit einem einzigen Namespace in Ihrem Projekt sind Sie gezwungen, andere Namen zu finden, und ich würde beschreibendere Namen wie diesen argumentieren:

  • Klasse Project1.ImageRectangle
  • Klasse Project1.WindowRectangle

Und die Verwendung ist überall gleich. Sie müssen sich nicht mit einem Sonderfall befassen, wenn eine Datei beide Typen verwendet.

mit Anweisungen

using Project1.General;  
using Project1.Image;  
using Project1.Window;  
using Project1.Window.Controls;  
using Project1.Shapes;  
using Project1.Input;  
using Project1.Data;  

vs.

using Project1;

Die Leichtigkeit, beim Schreiben von Code nicht ständig Namespaces hinzufügen zu müssen. Es ist nicht die Zeit, die es wirklich braucht, es ist die Unterbrechung des Flusses, es tun zu müssen und nur Dateien mit vielen verwendenden Anweisungen zu füllen - wofür? Lohnt es sich?

Struktur des Projektordners ändern

Wenn Ordner Namespaces zugeordnet sind, wird der Pfad des Projektordners effektiv in jeder Quelldatei fest codiert. Dies bedeutet, dass beim Umbenennen oder Verschieben einer Datei oder eines Ordners im Projekt der tatsächliche Dateiinhalt geändert werden muss. Sowohl die Namespace-Deklaration von Dateien in diesem Ordner als auch die Verwendung von Anweisungen in einer ganzen Reihe anderer Dateien, die auf Klassen in diesem Ordner verweisen. Während die Änderungen selbst mit Werkzeugen trivial sind, führt dies normalerweise zu einem großen Commit, das aus vielen Dateien besteht, deren Klassen sich nicht einmal geändert haben.

Mit einem einzelnen Namespace im Projekt können Sie die Projektordnerstruktur beliebig ändern, ohne dass Quelldateien selbst geändert werden.

Visual Studio ordnet den Namespace einer neuen Datei automatisch dem Projektordner zu, in dem sie erstellt wurde

Leider, aber ich finde, dass der Aufwand für die Korrektur des Namespace geringer ist als der Aufwand für den Umgang mit ihnen. Außerdem habe ich mir angewöhnt, eine vorhandene Datei zu kopieren und einzufügen, anstatt Add-> New zu verwenden.

Intellisense und Objektbrowser

Der größte Vorteil meiner Meinung nach bei der Verwendung mehrerer Namespaces in großen Projekten ist die zusätzliche Organisation beim Anzeigen von Klassen in Tools, die Klassen in einer Namespace-Hierarchie anzeigen. Sogar Dokumentation. Wenn nur ein Namespace im Projekt vorhanden ist, werden alle Klassen in einer einzigen Liste angezeigt und nicht in Kategorien unterteilt. Ich persönlich bin jedoch nie verblüfft oder verspätet, weil ich dies nicht habe. Daher finde ich es nicht groß genug, um mehrere Namespaces zu rechtfertigen.

Wenn ich eine große öffentliche Klassenbibliothek schreiben würde, würde ich wahrscheinlich mehrere Namespaces im Projekt verwenden, damit die Assembly in den Werkzeugen und in der Dokumentation ordentlich aussieht.

Weyland Yutani
quelle
30
Dies ist ehrlich gesagt eine der Albtraumlösungen, die ich vorgeschlagen habe. Wenn Sie an kleinen Hallo-Welt-Projekten arbeiten, funktioniert dieser Rat, aber stellen Sie sich vor, Sie haben mehr als 1000 CS-Dateien. Es würde so viele Probleme verursachen, dass ich nicht weiß, wo ich anfangen soll.
BentOnCoding
10
"Aber stellen Sie sich vor, Sie haben mehr als 1000 CS-Dateien". Ich habe in Projekten dieser Größe mit einem einzigen Namespace gearbeitet. Das ist gut. Welche Katastrophe würde Ihrer Meinung nach passieren?
Weyland Yutani
14
+1 zum Nachdenken. Ich glaube nicht, dass ich bereit bin, meine Namespaces auf einen pro Projekt zu reduzieren, aber nachdem ich an einem großen Framework gearbeitet habe, untersuche ich, die Anzahl der Namespaces zu reduzieren, um die Anzahl der verwendenden Anweisungen zu verringern und die Auffindbarkeit von Erweiterungsmethoden zu verbessern. Ich denke, diese Antwort gibt Anlass zum Nachdenken. Vielen Dank.
Lee Gunn
3
@WeylandYutani Ich weiß, ich bin zu spät, aber ich muss erwähnen, dass dieser Satz: you can find it by using Go To Definition or the search solution explorer box in Visual Studionicht immer wahr ist. Versuchen Sie es mit viel Vererbung und Schnittstellen ... viel Glück beim Finden der richtigen Datei.
Emmanuel M.
10
Dies ist einer der besten Ratschläge, die ich je gesehen habe. Namespaces dienen nur zur Konfliktlösung und nicht zum Organisieren von Klassen. Verwenden Sie Namespaces nur dort, wo es sinnvoll ist, sie zu verwenden, z. B. wenn Sie Namenskonflikte mit anderen Projekten erwarten, die möglicherweise Ihr Projekt verwenden, sodass bestimmte Namespaces bei der Verwendung von Anweisungen eingeschlossen oder ausgeschlossen werden können. Es ist schrecklich, kein Projekt mit 3 oder 4 oder mehr Namespaces zu haben, die häufig verwendet werden, da dies immer zu einer lächerlichen Anzahl von Anweisungen führt, die Sie hinzufügen und hinzufügen und hinzufügen und hinzufügen müssen. Brechen Sie Ihre Projekte auseinander.
Triynko
31

Ich denke, der Standard in .NET besteht darin, dies nach Möglichkeit zu versuchen, aber keine unnötig tiefen Strukturen zu erstellen, nur um es als harte Regel einzuhalten. Keines meiner Projekte folgt 100% der Zeit der Namespace == -Strukturregel. Manchmal ist es einfach sauberer / besser, aus solchen Regeln auszubrechen.

In Java haben Sie keine Wahl. Ich würde das einen klassischen Fall nennen, was theoretisch funktioniert und was in der Praxis funktioniert.

Karl Seguin
quelle
1
Ich würde sagen "Mach es, wenn du wirklich willst, dass sich etwas in einem eigenen Namespace befindet". Es sollte eine bewusste Entscheidung sein. Wenn Ihre Projekte ordnungsgemäß isoliert sind, sollte es sich um einen Namespace pro Projekt handeln. Wenn sich Ihre Klasse in einem Namespace befindet, sollte sie sich in einem Ordner mit diesem Namespace ODER einem Unterordner befinden, der mindestens so spezifisch ist wie der Namespace. Eine Klasse wie Car.Ford.Fusion (wenn Car.Ford Ihr einziger Namespace ist) sollte sich in einem Ordner wie Car / Ford oder tiefer wie Car / Ford / Sedans befinden, sodass der Ordner mindestens so spezifisch ist wie der Namespace. Setzen Sie es einfach nicht in Auto / Nicht verwandt / Ford; das ist verwirrend.
Triynko
25

@lassevk: Ich stimme diesen Regeln zu und muss noch eine hinzufügen.

Wenn ich verschachtelte Klassen habe, teile ich sie immer noch auf, eine pro Datei. So was:

// ----- Foo.cs
partial class Foo
{
    // Foo implementation here
}

und

// ----- Foo.Bar.cs
partial class Foo
{
    class Bar
    {
        // Foo.Bar implementation here
    }
}
Jay Bazuzi
quelle
5

Ich würde ja sagen.

Erstens ist es einfacher, die tatsächlichen Codedateien zu finden, indem Sie den Namespaces folgen (z. B. wenn Ihnen jemand einen nackten Ausnahmeaufrufstapel per E-Mail sendet). Wenn Sie Ihre Ordner nicht mehr mit Namespaces synchronisieren, wird es anstrengend, Dateien in großen Codebasen zu finden.

Zweitens generiert VS neue Klassen, die Sie in Ordnern mit demselben Namespace wie die übergeordnete Ordnerstruktur erstellen. Wenn Sie sich dagegen entscheiden, ist dies nur eine weitere Klempnerarbeit, die Sie täglich ausführen müssen, wenn Sie neue Dateien hinzufügen.

Dies versteht sich natürlich von selbst, dass man konservativ sein sollte, wie tief die Hierarchie von xis-Ordnern / Namespaces reicht.

Ishmaeel
quelle
4

Ja sollten sie, führt sonst nur zu Verwirrung.

Dan
quelle
2

Was ist der Standard?

Es gibt keinen offiziellen Standard, aber herkömmlicherweise wird das Zuordnungsmuster von Ordner zu Namespace am häufigsten verwendet.

In Klassenbibliotheken stimmen die Ordner normalerweise mit der Namespace-Struktur überein oder handelt es sich um eine gemischte Tasche?

Ja, in den meisten Klassenbibliotheken stimmen die Ordner aus organisatorischen Gründen mit dem Namespace überein.

user1451111
quelle