Was ist der effektivste Weg, um Code zwischen .NET-Anwendungen zu teilen?

13

In unserer Arbeit haben wir verschiedene .net-Anwendungen, die viele Basisfunktionen gemeinsam haben. Wir haben diese Anwendungen mit einer sauberen n-Tier-Architektur erstellt, aber wir haben den Moment erreicht, in dem wir feststellen, dass wir dieselben Funktionen mehrmals neu implementiert haben. Offensichtlich verletzt dies DRY und wir möchten das korrigieren. Wir verwenden Nuget bereits mit einigen Erfolgen für gängigen Klebercode (Verkabelung von IoC, Protokollierung, Einstellungen), möchten jedoch auch unsere Daten- und Geschäftsschichten für alle unsere Anwendungen freigeben. Die Idee ist, dass sich die Benutzeroberfläche nur mit den Teilen der Business-Schicht befasst, die sie tatsächlich benötigt.

Dies scheint zunächst ein einfaches Problem zu sein, aber die Weiterentwicklung könnte einige Fallstricke mit sich bringen, und wir sind uns nicht sicher, wie wir vorgehen sollen. Nehmen wir an, wir machen unsere One Business Layer, um sie alle zu regieren. Der Kürze halber nenne ich es "Foundation". Wir portieren unsere Anwendungen, um die Foundation zu nutzen, und alles läuft großartig. Die Foundation wird über Nuget an Light-UI-Layer verteilt, und wir sehen gut aus. Aber dann erweitern wir unsere Anwendungen um Funktionen, und es treten Probleme auf.

Angenommen, wir arbeiten an Projekt A und fügen eine neue Funktion hinzu, die Änderungen an Foundation erfordert. Wir nehmen die Änderungen an Foundation (Foundation-A) vor und leiten sie als instabiles Paket an den Nuget-Feed weiter. Projekt A erhält das neueste Nuget-Paket und alles ist gut. In der Zwischenzeit arbeitet ein anderer Entwickler an Projekt B. Er erhält die neueste Foundation aus der Quellcodeverwaltung, bezieht sie jedoch aus einem stabilen Zweig, sodass dort keine Änderungen an Projekt A vorgenommen werden. Er nimmt Änderungen vor und gründet Foundation-B. Und alles ist gut. Dann stellen wir jedoch fest, dass die Implementierungsfunktionen von Foundation-A und Foundation-B tatsächlich Code gemeinsam nutzen können. Deshalb kombinieren wir sie. In der Zwischenzeit schwebt Foundation-C mit seinen eigenen Änderungen da draußen. Schließlich ist Foundation-B für die Produktion bereit, und wir bringen es heraus. Aber dann müssen wir Produktion A, B aktualisieren,

Dies scheint möglich zu sein, aber wir sind besorgt darüber, dass wir mit verschiedenen Datenbankschemata arbeiten und alles zwischen den verschiedenen Zweigen des Foundation-Repository sowie den Projekt-A-, B- und C-Repositorys synchronisieren müssen. Es scheint, als würde es wahrscheinlich viel Handarbeit erfordern, was die Möglichkeit von Fehlern eröffnet. Ich möchte dies so automatisiert wie möglich.

Hier ist der Stack, den wir verwenden: C #, TFS mit Continuous Integration, Nuget. Unsere Anwendungen sind alle verschiedenen Arten von ASP.NET-Anwendungen. Wir sind bereit, uns verschiedene SCMs anzuschauen, wenn dies die Dinge einfacher macht.

Ich suche nach Wegen, um Nuget mit unseren verschiedenen Quellcode-Zweigen auf dem Laufenden zu halten. Wir möchten nicht versehentlich Entwicklungscode in die Produktion bringen, da wir auf das falsche Nuget-Paket verweisen.

Josh
quelle
Auch wenn dies kein gutes Forum für eine Diskussion wie diese ist, kann jemand ein besseres vorschlagen?
Josh

Antworten:

8

Wir nehmen die Änderungen an Foundation (Foundation-A) vor und leiten sie als instabiles Paket an den Nuget-Feed weiter.

Hier beginnt Ihr Problem ... Tun Sie das nicht.

Alle Änderungen an Foundation v1.0 sollten grundsätzlich für alle Benutzer von Foundation von Nutzen sein, da sie sonst nicht zu Foundation gehören. Wenn Sie also das Nuget-Paket erstellen, tun Sie dies als offizielle, stabile Version von Foundation (dh v1.1), oder tun Sie es überhaupt nicht.

Projekt B sollte seine Foundation-Erweiterungen wie gewohnt erstellen, jedoch (in guter Quellcodeverwaltung) die Stammänderungen (Version 1.1) zusammenführen, bevor eine stabile Foundation (Version 1.2) auf Nuget verschoben wird.

Andere Projekte, die die Foundation-Erweiterungen verwenden können, können ihre Nuget-Referenzen gegebenenfalls aktualisieren oder bei Bedarf bei den älteren Versionen bleiben.

Ich bin mit @Giedrius einverstanden . Dies scheint mir eher ein Problem der Quellcodeverwaltung / -verzweigung zu sein, da die Paketverwaltungsprobleme in Frage kommen, wenn die Verzweigung / Zusammenführung von Foundation ordnungsgemäß gehandhabt wird.

Eric King
quelle
Ja, das macht Sinn. Das Problem liegt in der praktischen Anwendung. Bei Aktualisierungen von Foundation for 1.1 möchten Sie diese Änderungen in Projekt B während der Entwicklung verwenden. Wenn Sie diesen Code über Nuget freigegeben haben, haben Sie folgende Möglichkeiten: 1) Veröffentlichen Sie ein neues Nuget-Paket, oder 2) Kopieren Sie die DLLs manuell. Beides scheint keine gute Wahl zu sein.
Josh
Ein Teil davon kann durch eine effektive Testsuite gemindert werden, aber es wird immer noch ein Hin und Her geben, wenn Sie Funktionen hinzufügen.
Josh
@Josh Ja, die Aktualisierungen für Foundation sollten vollständig und testbar sein, unabhängig davon, wie sie in Projekt B verwendet werden (da sie in eine gemeinsam genutzte Bibliothek verschoben werden). Daher ist das Veröffentlichen eines neuen Nuget-Pakets der natürliche Weg. Importieren und verwenden Sie Foundation v.Next in Projekt B erst, wenn es sich um ein stabiles Paket in Nuget handelt. Es braucht ein wenig Disziplin, aber es ist viel besser, als es anders zu machen.
Eric King
1
Ich verstehe vollkommen, was Sie sagen, aber ich denke nicht, dass es sehr realistisch ist. Selbst wenn Sie die gesamte Geschäftslogik- und Datenzugriffsebene vollständig getestet haben, werden bei der Entwicklung eines Features Änderungen vorgenommen, bevor es in die Produktion geht. Vielleicht stellen Sie fest, dass Sie der Geschäftslogik eine weitere Eigenschaft hinzufügen müssen, oder der Product Owner kehrt mit Änderungen oder Erläuterungen zurück. Vielleicht waren einige Ihrer vereinfachenden Annahmen falsch. Dies sind Dinge, die die ganze Zeit passieren. Wenn Sie sich auf die Freigabe Ihrer Basislogik beschränken, scheint dies in der Tat sehr begrenzt zu sein.
Josh
2
Da wir dies seit ein paar Monaten tun, haben wir uns im Grunde darauf geeinigt. Ich glaube, ich war zu besorgt über einen formellen Prozess. Sobald wir angefangen hatten, daran zu arbeiten, lief alles wirklich reibungslos. Danke für deinen Beitrag.
Josh
4

Zerlegen Sie Ihren duplizierten Code in Funktionen, die abstrakter anwendbar sind, und fügen Sie sie in ihre eigenen Bibliotheken oder Frameworks ein. Machen Sie sie lose gekoppelt und architekturunabhängig, und Sie sollten nie ein Problem haben. Wenn Sie Inspiration benötigen, lesen Sie, wie das .NET Framework Konzepte mithilfe von Schnittstellen, Generika und Softwaremustern wie z Dispose().

Denken Sie auch daran, dass nicht jeder doppelte Code wirklich dupliziert wird. Ein Teil davon ist Klebercode oder Code, der ansonsten für die Aufrechterhaltung der Architektur erforderlich ist. Seien Sie also nicht besessen davon, zu trocken zu sein.

Robert Harvey
quelle
Vielleicht war ich nicht so klar, wie ich es in meiner Frage könnte. Hier geht es darum, was als nächstes kommt. Sie haben das alles getan und müssen jetzt Ihren Code effektiv für Ihre verschiedenen Projekte freigeben. Jemand sagt, "benutze einfach Nuget dafür" und es hört sich großartig an, bis du auf Details und Probleme stößt - wie man verschiedene Änderungen von verschiedenen Zweigen und Anwendungen synchronisiert.
Josh
Nun, ich stimme Eric King zu. Der Foundation-Code sollte als stabile Version und nicht als instabile Version übertragen werden. Der Schlüssel ist die Aufrechterhaltung einer stabilen API: Wenn Sie wissen, dass sich die Signaturen Ihrer Foundation-Methoden nicht ändern werden, können Sie die Methoden sicher an Foundation weiterleiten und später umgestalten, ohne etwas zu beschädigen.
Robert Harvey
4

Code-Wiederverwendung

Im Laufe der Jahre hat es mehrere Ansätze zur Wiederverwendung von Code gegeben, die sich als vorteilhaft erwiesen haben. Jeder Ansatz hat seinen Platz und, was noch wichtiger ist, seine Probleme , aber die realisierbaren Möglichkeiten, Code in .NET wiederzuverwenden, sind:

  1. Gemeinsame Bibliothek. Der Code, der an mehr als einer Stelle benötigt wird, wird in eine gemeinsame Bibliothek gestellt, und alle anderen Teile der Codebasis haben dann einen einzigen Verweis auf diesen Code. Der grundsätzliche Nachteil ist, dass Sie den größten Teil Ihres Projekts in Abhängigkeit von dieser Bibliothek haben, die viele unabhängige Funktionen enthält. Aus Sicht der Qualitätssicherung ist dies eine schlechte Idee.

  2. Gemeinsamer Quellcode. Der Code, der an mehreren Stellen benötigt wird, wird einmal geschrieben und in einer Quelldatei in einer gemeinsamen Verzeichnisstruktur abgelegt. Alle Projekte, die diesen Code benötigen, schließen diese Datei dann als eine ihrer Quelldateien ein. Dies ermöglicht die Wiederverwendung von Code und die Vorteile des einmaligen und mehrfachen Schreibens. Jedoch. Der Nachteil ist, dass es möglich ist, verschiedene Teile des Projekts mit verschiedenen Versionen dieses Codes zu kompilieren. Dies kann zu subtilen Fehlern führen, die durch die Qualitätssicherung sehr schwierig zu erkennen und zu identifizieren sind.

  3. Bedienung. Der Common Code ist als Service implementiert, auf den andere Aspekte zugreifen können. Dies hat den Vorteil, dass in einer Bereitstellung nur ein einziger Dienst vorhanden ist und Abhängigkeiten vermieden werden. Es wird jedoch zu Latenz und Ausfällen führen. Dieser Ansatz eignet sich gut für Produkte mit großem Vertrieb, bei denen Hochverfügbarkeit und Fehlertoleranz bereits verstanden und verwaltet werden.

Verwalten von NuGET

Hier hast du ein viel interessanteres Problem. Mehrere Konfigurationen verwalten. Mein Rat hier ist, nicht einen diversen Kundenstamm mit verschiedenen Codeversionen zu verwalten, sondern mit Konfigurationsdateien. Es müssen mindestens drei Ebenen mit Konfigurationsdaten verwaltet werden. Grundlegende (interne) Produktkonfiguration, die der Kunde nie sieht. Die Standardkonfigurationsoptionen, die Ihr Kunde möglicherweise ändert, und die letzte Ebene der Konfigurationsoptionen, die Ihr Kunde geändert hat. Durch die Trennung dieser verschiedenen Ebenen können Sie Upgrades implementieren, ohne die Konfigurationen Ihrer Kunden zu zerstören.

Michael Shaw
quelle
1

Ich denke, das Problem liegt nicht in Nuget / Quellcodeverwaltung / Verzweigung, sondern darin, was sich in Code einfügt.

Robert hat eine nette Antwort, nur um das ganze Bild zu sehen, empfehle ich darüber nachzudenken, welche Abhängigkeiten diese allgemeinen Dienstprogramme in jedes Projekt bringen:

http://ayende.com/blog/3986/let-us-burn-all-those-pesky-util-common-libraries http://blog.jordanterrell.com/post/CommonUtility-Libraries-Dead.aspx

Der beste Weg, um der Hölle zu entgehen, besteht darin, Ihren Klebercode als Open Source-Datei zu veröffentlichen. Auf diese Weise wird es Sie interessieren, dass keine Geschäftslogik an die Öffentlichkeit geht, sodass keine konkreten Projektabhängigkeiten in den Klebercode einfließen, dass es abstrakt genug ist, um von irgendjemandem, auch außerhalb Ihres Unternehmens, wiederverwendet zu werden - und wenn das Kleber ist Code wird gut genug sein - Sie erhalten auch Community-Input.

Giedrius
quelle
Ich spreche nicht über das Verwalten von Klebercode. Wir haben bereits eine Lösung dafür und sie funktioniert gut. Ich spreche über das Teilen von Geschäftslogik. Unsere Anwendungen befassen sich beispielsweise mit dem Verwalten von Organisationen und Personen. Also müssen wir Erstellen Sie eine Person, und es gibt eine Reihe von Geschäftsregeln für die Erstellung einer Person. Anstatt sie mehrmals zu erstellen, möchten wir ein einziges Paket haben, das alles abdeckt, vom Erstellen des Objekts bis zum dauerhaften Speichern, das wir für die verschiedenen Projekte verwenden Das muss Menschen schaffen
Josh
0

Die Lösung ist einfach: Erstellen Sie ein separates Projekt, und verwalten Sie es als separate Sache: Es sind Ihre eigenen Anforderungen, Tests, Konventionen, Dokumentationen, Planungen, Personen usw. Auf diese Weise stellen Sie sicher, dass die Qualität hoch bleibt und mögliche Änderungen eintreten zuerst ausgewertet, bevor sie ein Problem erstellen.

Oder noch besser: Machen Sie es "Open Source" in Ihrem Unternehmen. So kann jeder den Code ändern, aber nur wenige ausgewählte Personen haben die vollen Festschreibungsrechte. Diese Personen sind für die Gewährleistung der Qualität und der korrekten Funktionen verantwortlich.

Euphorisch
quelle