Пример ветвления по абстракции для приложения ASP.NET MVC 3, где абстракция - разные страны - PullRequest
2 голосов
/ 11 августа 2011

Я работаю над приложением ASP.NET MVC 3, где для каждой страны созданы ветки в управлении версиями. Это затрудняет синхронизацию изменений между филиалами, и проблема будет увеличиваться по мере увеличения числа стран. Я читал о ветвлении по абстракции, но никогда не использовал его, поэтому я изо всех сил пытаюсь понять, как это могло бы быть реализовано в достаточно сложном проекте.

Может кто-нибудь объяснить, как ветвление по абстракции может быть сделано для приложения ASP.NET MVC, где абстракция - это страна, а приложение - дело n-уровневого типа со слоями обслуживания и данных?

Вот некоторые вещи, которые я не могу придумать:

  • Абстрактное представление вещей. Например. Файлы aspx / cshtml, javascript, css и т.д.
  • Абстрагирующие контроллеры
  • Как вы справляетесь с дополнительной сложностью иметь все ваши для кода каждая страна в одной отрасли? (Обратите внимание, под одной ветвью я подразумеваю ветку по умолчанию, магистраль, как хотите, чтобы она называлась)
  • Как вы управляете переключателями функций для каждой страны? Например. Потенциально у вас может быть много разных функций для каждой страны, которые не были готовы к выпуску и контролируются переключателем)
  • Как выбрать подходящую страну при развертывании?
  • Как вы запускаете модульные тесты для конкретной страны?

UPDATE

Я говорю не только об изменениях языка. Большая часть логики уровня обслуживания для каждой страны одинакова, но в определенных ключевых областях она различна, также как и для уровня данных. Кроме того, вид содержимого и макет могут отличаться, JavaScript может отличаться, и логика контроллера может отличаться.

Ответы [ 3 ]

4 голосов
/ 11 августа 2011

Почему вы используете ветки для обработки локализации? имхо это безумие

Существует несколько способов локализации без использования одной кодовой базы для каждого языка.

Например. Создав собственный движок представлений поверх существующего, вы можете загружать представления из внешних сборок. Или вы можете создать одно представление для каждого языка.

Вы также можете использовать строковые таблицы в своих представлениях, чтобы сделать их локализованными.

Абстрактное представление вещей. Например. Файлы aspx / cshtml, javascript, css и т. Д.

Javascripts: у меня есть один javascript со всей моей логикой, который использует переменные вместо строк для отображения сообщений. Таким образом, я могу загрузить другой javascript перед логическим скриптом (например, myplugin.sv.js до myplugin.js, чтобы получить шведский язык.

Наиболее распространенный способ для файлов aspx / cshtml - использовать в них строковые таблицы.

Локализовать CSS? Почему?

Абстрагирующие контроллеры

да? Зачем? Используйте здесь также строковые таблицы.

Как вы справляетесь со сложностью наличия всех ваших кодов для каждой страны в одной отрасли?

Не используйте ветки.

Как вы управляете переключениями функций для каждой абстракции?

да

Как выбрать подходящую страну при развертывании?

Используйте один и тот же сайт для всех языков. Для выбора языка используйте IP-адрес, заголовок Accept-Language http или языковые предпочтения пользователя. Язык указывается настройкой Thread.CurrentThread.CurrentCulture и Thread.CurrentThread.CurrentUICulture

Как вы запускаете модульные тесты для конкретной страны?

Не. Логика должна быть такой же.

Обновление в ответ на ваш комментарий

Я написал довольно много систем, в которых контент динамически загружается в приложение / службу. Я никогда не использовал разные базы кода, даже если разные клиенты используют разные функции в мультитенантных системах (SaaS).

Прежде всего, вам нужно принять две вещи:

a) Весь контент загружается постоянно (не о переводах, а о возможностях). б) Используйте надлежащие / стандартные методы локализации, но нет необходимости переводить все функции на все языки.

Что вы делаете, просто контролируете, какой контент загружать, и используете стандартные методы для получения переведенных функций. Управление осуществляется путем проверки текущего языка (Thread.CurrentThread.CurrentCulture.Name) или любого самодельного элемента управления.

Задайте новые вопросы, чтобы получить больше деталей.

Обновление 2

Я бы не стал полагаться на IoC для предоставления специфичных для языка функций, но использовал бы для этого рефлексию и класс FeatureProvider.

Например, допустим, у вас есть функция с именем ISalaryCalculator, которая учитывает все местные налоговые правила и т. Д., Тогда я бы создал что-то вроде этого:

// 1053 is the LCID (read about LCID / LocaleId in MSDN)
[ForLanguage(1053)]
public SwedishSalaryCalculator : ISalaryCalculator
{
}

И есть FeatureProvider, чтобы загрузить его:

public class FeatureProvider 
{
    List<Assembly> _featureAssemblies;

    public T GetLocalFeature<T>()
    {
        var featureType = typeof(T);
        foreach (var assembly in _featureAssemblies)
        {
            foreach (var type in assembly.GetTypes().Where(t => featureType.IsAssignableFrom(t))
            {
                var attribute = type.GetCustomAttributes(typeof(ForLanguageAttribute)).First();
                if (attribute.LocaleId == Thread.CurrentThread.CurrentCulture.LCID)
                    return (T)Activator.CreateInstance(type);
            }
        }
        return null;
    }
}

И чтобы получить функцию (для текущего языка):

var calculator = _featureManager.GetLocalFeature<ISalaryCalculator>();
var salaryAfterTaxes = calculator.GetSalaryAfterTax(400000);
1 голос
/ 11 августа 2011

В простом сценарии (CMS / не много или общая бизнес-логика) вы имеете дело только с контентом на разных языках и:

  1. Макет (слева направо или справа)слева) - у вас будет два CSS-файла
  2. Локализованный (переведенный) контент

Макет CSS может находиться в отдельных файлах и может быть выбран в зависимости от культуры учетной записи пользователя или региона сайта.

Локализация может находиться в разных сборках - по одной для каждой культуры или в отдельных файлах таблицы строк (как уже упоминалось).

В более сложном сценарии , гдеВы разрабатываете приложение для чувствительных культур и регионов, в которых:

  1. Вы должны быть осторожны с отображаемым контентом - например, изображение может быть очень оскорбительным в одной стране, но в другой стране вполне подходящим.
  2. Различная бизнес-логика (например, финансовое приложение и т. Д.)

Большинство проблем с контентом, которые вы можете решить с помощью CSS, но даже если вам нужны сильно настроенные представления, как уже упоминалосьВы можете создать механизм представления, который извлекает файл представления на основе текущей культуры (например, Index.en-Us.cshtml, Index.ru.cshtml и т. д.)

Для различных бизнес-правил вы должны иметь хорошийпроектирование и архитектура с использованием инверсии управления (например, внедрение зависимости) и таких шаблонов, как стратегия, состояние, метод шаблона и т. д. При наличии такой возможности вы сможете создавать контейнерный проект / сборку IoC для каждой культуры во время выполненияи ваш пользовательский интерфейс не будет знать о разнице, поскольку он будет просто потреблять некоторые службы, определенные этими интерфейсами.

Немного сложнее, если ваши ViewModel значительно различаются между культурами, но, если они есть, вы, возможно, захотите разделить View + Controller на культуру в разных сборках и снова использовать IoC для настройки маршрутизации при инициализации во время выполнения.

Очевидно, что развертывание мультикультурных сайтов сложнее, чем несуразных, и независимо от того, каким путем вы идете (экземпляр сайта для культуры или один сайт для всех культур), вы, вероятно, захотите инвестировать в какой-то инструментарий, чтобы иметь возможностьдля сценария развертывания нескольких культур.

И последнее - в отношении модульных тестов - если у вас уже есть хорошее тестирование дизайна на основе IoC для каждой культуры, нужно будет использовать и настроить правильный контейнер зависимостей до запуска наборамодульных тестов.

При такой настройке команды разработчиков должны работать в относительно автономной среде, поскольку ваш проект будет логически и физически разделен для поддержки нескольких групп, работающих над отдельнымиискусство этого в то же время.Это также не должно иметь значения, будь то ветки или ствол / голова.Конечно, если в нескольких проектах все в большом беспорядке, и люди должны постоянно сливаться - вы в очень плохом состоянии и ваше будущее не светлое.

Заключительные слова: это не тако ветвлении - о дизайне, архитектуре, разбиении (решения, проекты и сборки) и, наконец, что не менее важно, об автоматизации (сборка и тестирование).

0 голосов
/ 11 августа 2011

Это немного не по теме, но я считаю, что вы движетесь в более сложном направлении, чем нужно. Локализация встроена в ASP.NET, и инфраструктура MVC также может этим воспользоваться.

Короче говоря, вы делаете рекс для каждого языка, который хотите поддерживать. Затем вы используете Resources.Global.YourLocalizedStringPropertyName в своих представлениях.

Это сообщение в блоге длинная история. Скотт Хансельман изучает локализацию JavaScript и другие тонкости. Это определенно стоит прочитать и, вероятно, сэкономит вам невероятное количество работы, чтобы использовать встроенную функциональность вместо того, чтобы создавать ее самостоятельно:

http://www.hanselman.com/blog/GlobalizationInternationalizationAndLocalizationInASPNETMVC3JavaScriptAndJQueryPart1.aspx

...