Який найефективніший спосіб ділитися кодом між .NET-додатками?


15

У своїй роботі у нас є кілька різних .net-додатків, які мають багато базових функціональних можливостей. Ми створили ці програми за допомогою чистої n-ярусної архітектури, але ми потрапили в той момент, коли зрозуміли, що повторно реалізували одні і ті ж функції кілька разів. Очевидно, це порушує DRY, і ми хотіли б це виправити. Ми вже використовуємо Nuget для успішного використання загального коду клею (підключення IoC, ведення журналів, налаштувань), але ми також хотіли б поділитися нашими даними та бізнес-шарами між усіма нашими програмами. Ідея полягає в тому, що інтерфейс користувача матиме справу лише з частинами бізнес-шару, які йому фактично потрібні.

Спочатку це здається прямою проблемою, але постійний розвиток може забезпечити деякі підводні камені, і ми не впевнені, як діяти далі. Скажімо, ми робимо наш єдиний бізнес-рівень, щоб правити їм усім. Для стислості я назву це «Фундація». Ми портуємо наші програми для використання фонду, і все працює чудово. Фундація поширюється на легкі шари інтерфейсу через nuget, і ми добре виглядаємо. Але потім ми починаємо додавати функції до наших програм, і ми стикаємося з проблемою.

Скажімо, ми працюємо над проектом A і додаємо нову функцію, яка потребує змін у Foundation. Ми вносимо зміни до фонду (Foundation-A) і висуваємо їх до нульового каналу як нестабільний пакет. Проект A отримує найновіший пакунок нута, і все добре. Тим часом, інший розробник працює над проектом B. Він отримує останній фонд від контролю джерел, але бере його від стабільної гілки, щоб у ньому не було змін Проекту А. Він вносить зміни і створив Foundation-B. І все добре. Але потім ми виявимо функціонал реалізації Foundation-A та Foundation-B, який фактично міг би ділитися кодом, тому ми їх поєднуємо. Тим часом Foundation-C пливе туди з власними змінами. Зрештою, Фонд-Б готовий до виробництва, тому ми його витісняємо. Але тоді нам потрібно оновити Виробництво A, B,

Здається, це могло б працювати, але ми стурбовані роботою з різними схемами баз даних і збереженням синхронізованого між різними гілками сховища Foundation, а також сховищами проектів A, B і C. Схоже, напевно знадобиться багато ручної роботи, що відкриває можливість помилок. Я хотів би, щоб це було максимально автоматизованим.

Ось стек, який ми використовуємо: C #, TFS з постійною інтеграцією, Nuget. Наші програми - це всі різні типи програм ASP.NET. Ми готові подивитися на різні SCM, якщо це полегшить ситуацію.

Я шукаю способи зберегти Нугет в розумі з нашими різними гілками вихідного коду. Ми не хочемо випадково впроваджувати код розробки у виробництво, оскільки ми посилаємося на неправильний Nuget Package.


Крім того, якщо це не гарний форум для такої дискусії, чи може хтось запропонувати кращий?
Джош

Відповіді:


9

Ми вносимо зміни до фонду (Foundation-A) і висуваємо їх до нульового каналу як нестабільний пакет.

Ось де починається ваша проблема ... Не робіть цього.

Будь-які зміни до фонду v1.0 мають бути притаманні всім споживачам Фонду, інакше він не належить до фонду. Отже, створюючи пакет nuget, робіть це як офіційну, стабільну версію Foundation (тобто v1.1), або не робіть цього взагалі.

Проект B повинен будувати свої вдосконалення Фонду так, як зазвичай, але (при належному режимі управління джерелами) повинен зливатися в змінах ствола (v1.1), перш ніж підштовхувати стабільний фонд (v1.2) до нуля.

Інші проекти, які можуть використовувати вдосконалення Фонду, можуть, якщо це доречно, оновити свої чіткі посилання або дотримуватися старіших версій, якщо це потрібно.

Я погоджуюся з @Giedrius ; мені здається, це скоріше питання контролю джерела / розгалуження, в тому сенсі, що якщо розгалуження / злиття Foundation керується належним чином, питання управління пакетом стають суперечливими.


Так, це має сенс. Проблема полягає у практичному застосуванні. Коли ви робите оновлення до Foundation for v1.1, ви хочете використовувати ці зміни в Project B під час розробки. Якщо ви поділилися цим кодом через nuget, то ваші параметри: 1) опублікувати новий пакунок нута, або 2) копіювати dll вручну. Жоден із них не здається хорошим вибором.
Джош

Дещо з цього можна пом'якшити за допомогою ефективного тестового набору, але ви все ще будете повертатися назад і назад, коли ви додаєте функції.
Джош

@Josh Так, оновлення до Фонду повинні бути повними та перевіреними незалежно від того, яким чином проект B їх використовуватиме (оскільки вони збираються у спільну бібліотеку), тому "опублікувати новий пакунок" - це природний шлях. Не імпортуйте та не використовуйте Foundation v.Next в проекті B, поки це не буде стабільним пакетом у nuget. Це вимагає трохи дисципліни, але це набагато краще, ніж безлад робити це інакше.
Ерік Кінг

1
Я повністю розумію, що ви говорите, але не думаю, що це дуже реально. Коли ви розробляєте функцію, навіть якщо ви повністю перевірені весь рівень бізнес-логіки та рівня доступу до даних, перед введенням у виробництво відбудеться модифікація. Можливо, ви усвідомлюєте, що потрібно додати іншу властивість до бізнес-логіки, або власник продукту повертається зі змінами чи уточненнями. Можливо, деякі ваші спрощення припущень помилялися. Це речі, які відбуваються постійно. Якщо ви обмежуєтесь блокуванням випущеної вашої базової логіки, це здається дуже обмеженим.
Джош

2
Оскільки ми робимо це вже кілька місяців, це в основному те, на чому ми вирішили. Я думаю, що я занадто хвилювався, щоб провести офіційний процес. Як тільки ми почали реально працювати над цим, все закінчилося дуже гладко. Дякуємо за ваш внесок.
Джош

4

Перефактуруйте свій дублікат коду на функції, застосовані більш абстрактно, і помістіть їх у власні бібліотеки чи рамки. Зробіть їх вільно зв'язаними та архітектурно-агностичними, і у вас ніколи не виникне жодних проблем. Якщо вам потрібно натхнення, вивчіть, як .NET Framework абстрагує поняття, використовуючи такі речі, як інтерфейси, дженерики та такі програмні зразки, як Dispose().

Також пам’ятайте, що не всі копії коду дійсно дублюються; Деякі з них - це клей-код або код, який інакше необхідний для підтримки архітектури, тому не зациклюйтеся на тому, щоб бути занадто СУХИМ.


Можливо, я не був таким чітким, як міг би бути у своєму питанні. Йдеться про те, що йде далі. Ви все зробили, і тепер вам потрібно ефективно ділитися кодом між вашими різними проектами. Хтось каже, що "просто використовуйте для цього", і це чудово звучить, поки ви не вникнете в деталі і не зіткнетеся з проблемами - як, наприклад, як синхронізувати різні зміни в різних галузях і програмах.
Джош

Ну, я згоден з Еріком Кінгом. Код фундаменту слід висувати як стабільну версію, а не нестабільну. Ключовим моментом є підтримка стабільного API: якщо ви знаєте, що підписи ваших методів основи не збираються змінюватися, ви можете сміливо підштовхувати методи до фундаменту та переробляти їх пізніше, нічого не порушуючи.
Роберт Харві

4

Повторне використання коду

Існувало кілька підходів до повторного використання коду, які знайшли прихильність протягом багатьох років. У кожного підходу є своє місце і, що ще важливіше, його питання , але життєздатними способами повторного використання коду в .NET є:

  1. Загальна бібліотека. Код, який потрібен у більш ніж одному місці, вводиться до загальної бібліотеки, а всі інші частини бази коду мають єдине посилання на цей код. Недоліком принципу є те, що ви закінчуєте більшість своїх проектів залежно від цієї бібліотеки, яка містить безліч непов'язаних функцій. Це погана ідея з аспекту забезпечення якості.

  2. Загальний вихідний код. Код, який потрібен у більш ніж одному місці, пишеться один раз і розміщується у вихідному файлі у загальній структурі каталогів. Усі проекти, яким потрібен цей код, включають цей файл як один із вихідних файлів. Це забезпечує повторне використання коду, а переваги написання одного разу використовують багато. Однак. Його недоліком є ​​те, що стає можливим складання різних частин проекту, складених з різними версіями цього коду, - що може ввести деякі тонкі дефекти, які можна виявити і визначити за допомогою забезпечення якості.

  3. Сервіс. Загальний код реалізований як послуга, до якої можуть отримати доступ інші аспекти. Це має перевагу в тому, що в розгортанні буде одна служба, а також уникнути залежностей. Однак це призведе до затримки та відмов. Такий підхід добре працює у великих розповсюджених продуктах, де висока доступність та відмовостійкість вже зрозумілі та керовані.

Управління NuGET

Тут у вас набагато цікавіша проблема. Керування декількома конфігураціями. Моя порада тут - не керувати різноманітною базою клієнтів з різними версіями коду, а з файлами конфігурації. Існує щонайменше 3 шари даних конфігурації для управління. Базова (внутрішня) конфігурація товару, яку замовник ніколи не бачить. Параметри конфігурації за замовчуванням, які може змінити ваш клієнт, і останній рівень параметрів конфігурації, які змінив ваш клієнт. Розділяючи ці різні шари, ви зможете виконувати оновлення без руйнування конфігурацій клієнтів.


1

Я думаю, проблема полягає не в керуванні / розгалуженні джерел / розгалуженні, а в тому, що ковзає в склеювальний код.

Роберт має гарну відповідь, просто щоб побачити всю картину, рекомендую подумати про те, які залежності ці загальні утиліти приведуть у кожен проект:

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

Найкращий спосіб уникнути пекла, який ви маєте, це відкрити вихідний код свого клею. Таким чином, ви почнете дбати про те, щоб жодна логіка бізнесу не стала публічною, тому жодна конкретна залежність від проекту не прослизне в клей-код, що це було б досить абстрактно, щоб його повторно використовували будь-хто, навіть поза вашою компанією - і якщо це клеїти код буде досить хорошим - ви також отримаєте вклад спільноти.


Я не говорю про керування клей-кодом. У нас вже є рішення для цього, і воно добре працює. Я говорю про ділову логіку. Наприклад, наші програми мають справу з керуючими організаціями та людьми. Отже, нам потрібно створити людину, і існує купа ділових правил, пов’язаних із тим, як людина повинна бути створена. Замість того, щоб створювати її кілька разів, ми хочемо мати один пакет, який обробляє все, починаючи від побудови об'єкта, до його збереження, яким ми ділимось між різними проектами що потрібно створити людей.
Джош

0

Рішення просте: створити для нього окремий проект і керувати ним як окрема річ: це власні вимоги, тестування, конвенції, документація, планування, люди тощо. Таким чином, ви гарантуєте, що якість залишається високою та можливі можливі зрушення. оцінюється спочатку, перш ніж створити проблему.

Або ще краще: зробіть це "відкритим кодом" у вашій організації. Таким чином, кожен може змінити код, але лише деякі вибрані люди матимуть повні права на виконання зобов'язань. І ці люди будуть нести відповідальність за забезпечення якості та правильних функцій.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.