Pregunta

EDIT:

Debido a que era demasiado tarde con la concesión de la recompensa inicial de 300 a @arcain estoy reapertura. Y la adjudicación de la 150 adicional para @arcain. A menos que, por supuesto, alguien ofrece incluso una mejor respuesta. :)

/ EDIT

Considere la siguiente forma:

language | region | active | default |
-----------------------------------------------
en       | GB     | [x]    | (*)     | [X delete]
nl       | NL     | [x]    | ( )     | [X delete]
nl       | BE     | [x]    | ( )     | [X delete]

[x] let visitors browser-settings determine the default language

[save]

Los valores de la tabla anterior se guardarán en una tabla de base de datos las columnas que se asignan a las columnas anteriores (excluyendo la última columna obviamente).

Todo (Guardar y borrar) acciones directas a un controlador de localización. El controlador de localización llama básicamente métodos en un LocalizationService, así:

$localizationService->updateCollection( $_POST ) // update collection settings
// or
$localizationService->delete( $_POST ) // delete a single locale

El LocalizationService en él es a su vez llama a un LocaleMapperDb, algo como esto:

foreach( $localeCollection as $locale )
{
    $localeMapperDb->update( LocaleModel $locale );
}
// or
$localeMapperDb->delete( LocaleModel $locale );

Cuando, sin embargo, es la responsabilidad de salvar esta configuración:

[x] let visitors browser-settings determine default language

Se guarda en una tabla de base de datos llamada site_settings. He pensado en algunas opciones:

  • Utilice un SiteService / SiteSettingsService en el LocalizationController. Pero entonces, se genera la forma completa y procesada en los LocalizationService ya.
  • Utilice un SiteMapperDb / SiteSettingsMapperDb en el LocalizationService y utilizarlo en updateCollection ($ _POST)
  • Utilice un SiteMapperDb / SiteSettingsMapperDb en el LocaleMapperDb

Las primeras y últimas opciones se parecen a las peores opciones, pero no estoy seguro. ¿Cuáles cree que es la mejor opción? O tal vez tenga una opción alternativa, no he pensado?

¿Fue útil?

Solución

Creo que la proyección de modelo de objetos de dominio en vista del modelo de objetos funciona bien en esta situación.

En el caso del código adjunto (por favor, perdóname por escribirlo en C #, sino que debe ser bastante portátil) los objetos del modelo de dominio nunca se exponen (que sólo se accede directamente dentro de los objetos de servicio.) Los servicios sólo exponen vista los objetos del modelo, como LocalViewModel, y aquellos objetos vista de modelo son manipulados por los controladores.

El LocaleConfigController también mapea los datos devueltos por los servicios en un objeto LocaleConfigViewModel, y este objeto es el único objeto que se intercambia directamente con la vista.

Por lo tanto, en pocas palabras, la vista tiene un controlador dedicado, y la vista comunica con el controlador a través del objeto LocaleConfigViewModel. El controlador manipula el objeto LocaleConfigViewModel y llamadas en implementaciones de la ILocaleConfigService y la ISystemConfigService. El servicio nunca objetos exponer el modelo de dominio al controlador, y que son responsables de objetos vista mapeo modelo a los objetos del modelo de dominio (a través de cualquier mecanismo de persistencia es deseable.)

Tenga en cuenta que el servicio de localización es un configuración servicio, no tendría ninguna aplicación para buscar cuáles serían las cadenas localizadas correctas. Me gustaría poner esto en otro servicio, ya que podría ser utilizado en lugares donde no se desea exponer utilización de métodos que permitan la alteración de la configuración de la localización.

Por ejemplo, en el lado de la gestión de la aplicación, se querría tanto el servicio de localización de configuración y servicio de localización cadena de prestación (ya que el sitio de gestión se podrá ubicar también.) Para un cliente mirando hacia el extremo frontal, lo haría en su lugar, probablemente, quiere sólo el servicio de renderizado cadena localización, porque las modificaciones de configuración del sistema deben ser no deseado y fuera del alcance de ese sitio.

Así que, para responder finalmente a la pregunta:. El controlador contiene referencias tanto a los servicios de la configuración del local y del sistema, y ??el controlador está dedicada a la vista - que tiene un contrato bien definido donde se intercambian sólo LocaleConfigViewModels

En cuanto a donde se encuentra la responsabilidad de guardar la configuración de todo el sistema, el controlador se encarga de desembalar la configuración del sistema de la LocaleConfigViewModel y empujándolos hacia los servicios apropiados (en este caso la instancia ISystemConfigService) donde serán persistieron.

class LocaleViewModel
{
  public int Id;
  public string Language;
  public string Region;
  public bool Enabled;
  public bool Deleted;
}

class LocaleConfigViewModel
{
  public bool UseVisitorBrowserLocale;
  public LocaleViewModel DefaultLocale;
  public List<LocaleViewModel> Locales; 
}

class LocaleConfigController : ILocaleConfigController
{
  ILocaleConfigService localeConfig;
  ISystemConfigService systemConfig;

  public void Save(LocaleConfigViewModel model)
  {
    foreach (var locale in model.Locales)
    {
      if (locale.Deleted)
      {
        localeConfig.DeleteLocale(locale);
        continue;
      }
      localeConfig.UpdateLocale(locale);
    }
    systemConfig.DefaultLocaleId = model.DefaultLocale.Id;
    systemConfig.UseVisitorBrowserLocale = model.UseVisitorBrowserLocale;
  }

  public LocaleConfigViewModel GetCurrentView()
  {
    var model = new LocaleConfigViewModel();
    model.Locales = localeConfig.Locales;
    model.DefaultLocale = model.Locales.FirstOrDefault(l => l.Id == systemConfig.DefaultLocaleId);
    model.UseVisitorBrowserLocale = systemConfig.UseVisitorBrowserLocale;
    return model;
  }

  // ...
}

interface ILocaleConfigController
{
  void Save(LocaleConfigViewModel model);
  LocaleConfigViewModel GetCurrentView();
  // ... 
}

interface ILocaleConfigService // services will be stateless and threadsafe
{
  void DeleteLocale(LocaleViewModel locale);
  void UpdateLocale(LocaleViewModel locale);
  List<LocaleViewModel> Locales { get; }
  // ...
}

interface ISystemConfigService // services will be stateless and threadsafe
{
  int DefaultLocaleId { get; set; }
  bool UseVisitorBrowserLocale { get; set; }
  // ...
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top