Escrevendo um método sustentável cometer
-
05-07-2019 - |
Pergunta
Eu tenho um ViewModel que encapsula algumas propriedades que estão sendo editados em um diálogo de opções. Eu não pode realmente salvar-lhes as configurações até que atingiu o botão Ok, o que vai acabar chamando Commit neste ViewModel particular.
A única propriedade em minha aparência ViewModel como esta:
public bool SomeProperty
{
get
{
return m_SomeProperty;
}
set
{
if (m_SomeProperty != value)
{
m_SomeProperty = value;
NotifyPropertyChanged("SomeProperty");
}
}
}
private bool m_SomeProperty = Properties.Settings.Default.SomeProperty;
Assim, a implementação normal para Commit seria fazer isso:
public void Commit()
{
Properties.Settings.Default.SomeProperty = m_SomeProperty;
// Add other properties here...
}
Isto não é tão ruim, mas a razão pela qual eu não gosto disso é que se você adicionar uma nova propriedade, você tem que adicionar código para ele em dois lugares. Eu tento evitar que, quando possível.
No começo eu pensei que eu poderia declarar um evento privado chamado OnCommit e ter a Commit raise método esse evento, e tem o código para cada propriedade adicionar um manipulador de eventos para o evento e fazer a escrita para as configurações de lá, mas eu don 't sabe como fazer isso sem adicionar os manipuladores de eventos no construtor de qualquer maneira, o que não ajuda a situação.
Todas as idéias? Alguém tem uma maneira elegante de fazer o que estou tentando fazer?
Editar : Graças a sixlettervariables para a resposta. Tomei essa idéia e incorporou em SoapBox Núcleo e código aberto o resultado. Confira o diálogo Opções para ver como ele funciona.
Solução
Talvez manter uma lista de Action
s para executar?
private List<Action> commitActions = new List<Action>();
public bool SomeProperty
{
get
{
return m_SomeProperty;
}
set
{
if (m_SomeProperty != value)
{
m_SomeProperty = value;
lock (commitActions)
{
commitActions.Add(
() => Properties.Settings.Default.SomeProperty = value);
}
NotifyPropertyChanged("SomeProperty");
}
}
}
Em seguida, atualize o seu código Commit
para percorrer as ações.
public void Commit()
{
List<Action> commits;
lock (commitActions)
{
commits = new List<Action>(commitActions);
commitActions.Clear();
}
foreach (var commit in commits)
{
commit();
}
}
Outras dicas
Você poderia usar o reflexo para determinar quais propriedades de sua classe tem e iterate através deles?