Em fevereiro de 2019, foi lançado o 
ReactiveUI 9 , uma estrutura de plataforma cruzada para a criação de aplicativos GUI na plataforma Microsoft .NET. 
O ReactiveUI é uma ferramenta para integrar firmemente extensões reativas ao padrão de design do MVVM. O conhecimento da estrutura pode ser iniciado com uma 
série de artigos sobre Habré ou 
na primeira página da documentação . A atualização do ReactiveUI 9 inclui muitas 
correções e melhorias , mas talvez a mudança mais interessante e significativa seja a 
forte integração com a estrutura DynamicData , que permite trabalhar com a alteração de coleções em um estilo reativo. Vamos tentar descobrir em que casos o 
DynamicData pode ser 
útil e como essa poderosa estrutura reativa é organizada por dentro!
Antecedentes
Primeiro, definimos o intervalo de tarefas que o 
DynamicData resolve e descobrimos por que as ferramentas padrão para trabalhar com a alteração de conjuntos de dados no namespace 
System.Collections.ObjectModel não nos convém.
O modelo MVVM, como você sabe, envolve a divisão de responsabilidade entre as camadas do modelo, apresentação e modelo de apresentação do aplicativo. A camada de modelo é representada por entidades e serviços de domínio e não sabe nada sobre o modelo de apresentação. A camada do modelo encapsula toda a lógica complexa do aplicativo e o modelo de apresentação delega as operações do modelo, fornecendo à visualização acesso a informações sobre o estado atual do aplicativo por meio de propriedades, comandos e coleções observáveis. A ferramenta padrão para trabalhar com propriedades alteradas é a interface 
INotifyPropertyChanged , 
INotifyPropertyChanged para trabalhar com ações do usuário e 
INotifyCollectionChanged implementar coleções e implementar 
ObservableCollection e 
ReadOnlyObservableCollection .

A implementação de 
INotifyPropertyChanged e 
ICommand geralmente permanece na consciência do desenvolvedor e da estrutura MVVM usada, mas o uso de 
ObservableCollection impõe várias restrições! Por exemplo, não podemos alterar uma coleção de um encadeamento em segundo plano sem 
Dispatcher.Invoke ou uma chamada semelhante, e isso pode ser útil no caso de trabalhar com matrizes de dados que alguma operação em segundo plano sincronize com o servidor. Deve-se notar que, no MVVM idiomático, a camada de modelo não precisa conhecer a arquitetura do aplicativo GUI usado e ser compatível com o modelo do MVC ou MVP, e é por isso que vários 
Dispatcher.Invoke permitem acesso ao controle da interface do usuário a partir do encadeamento em execução em um serviço de domínio, viole o princípio de compartilhar responsabilidades entre as camadas de aplicativos.
Obviamente, em um serviço de domínio, seria possível declarar um evento e, como argumento de um evento, transmitir um pedaço com dados alterados. Em seguida, inscreva-se no evento, envolva a chamada 
Dispatcher.Invoke em uma interface para que ela não dependa da estrutura da GUI usada, mova 
Dispatcher.Invoke para o modelo de apresentação e altere a 
ObservableCollection necessário, no entanto, existe uma maneira muito mais simples e elegante de resolver o intervalo de tarefas indicado sem precisar escrever uma bicicleta . Vamos começar o estudo!
Extensões reativas. Gerenciar fluxos de dados
Para um entendimento completo das abstrações introduzidas pelo 
DynamicData e dos princípios de trabalhar com a alteração de conjuntos de dados reativos, lembremos o 
que é programação reativa e como aplicá-la no contexto da plataforma Microsoft .NET e do padrão de design MVVM . Uma maneira de organizar a interação entre os componentes do programa pode ser interativa e reativa. Na interação interativa, a função do consumidor recebe dados de forma síncrona da função do provedor (abordagem baseada em pull, 
T , 
IEnumerable ) e, na interação reativa, a função do consumidor entrega assincronamente dados para a função do consumidor (abordagem baseada em push, 
Task , 
IObservable ).
 A programação reativa
A programação reativa é a programação usando fluxos de dados assíncronos, e as extensões reativas são um caso especial de sua implementação, com base nas 
IObserver IObservable e 
IObserver do namespace System, que define várias operações semelhantes a LINQ na interface 
IObservable , denominadas LINQ over Observable. As extensões reativas suportam o .NET Standard e funcionam onde quer que a plataforma Microsoft .NET funcione.

A estrutura ReactiveUI convida os desenvolvedores de aplicativos a aproveitar a implementação reativa de 
ICommand e 
INotifyPropertyChanged , fornecendo ferramentas poderosas como 
ReactiveCommand<TIn, TOut> e 
WhenAnyValue . 
WhenAnyValue permite converter uma propriedade de uma classe que implementa INotifyPropertyChanged em um fluxo de eventos do tipo 
IObservable<T> , que simplifica a implementação de propriedades dependentes.
 public class ExampleViewModel : ReactiveObject { [Reactive]  
ReactiveCommand<TIn, TOut> permite que você trabalhe com o comando, como em um evento do tipo 
IObservable<TOut> , publicado sempre que o comando concluir a execução. Além disso, qualquer comando possui uma propriedade 
ThrownExceptions do tipo 
IObservable<Exception> .
 
Todo esse tempo trabalhamos com 
IObservable<T> , como em um evento que publica um novo valor do tipo 
T sempre que o estado do objeto que está sendo monitorado é alterado. Simplificando, 
IObservable<T> é um fluxo de eventos, uma sequência estendida ao longo do tempo.
Obviamente, poderíamos trabalhar de maneira tão fácil e natural com as coleções - sempre que uma coleção for alterada, publique uma nova coleção com elementos alterados. Nesse caso, o valor publicado seria do tipo 
IEnumerable<T> ou mais especializado, e o próprio evento seria do tipo 
IObservable<IEnumerable<T>> . Mas, como o leitor que pensa criticamente corretamente aponta, isso está repleto de sérios problemas com o desempenho do aplicativo, especialmente se não houver uma dúzia de elementos em nossa coleção, mas uma centena ou até vários milhares!
Introdução ao DynamicData
DynamicData é uma biblioteca que permite que você use toda a potência de extensões reativas ao trabalhar com coleções. As extensões reativas prontas para uso não oferecem maneiras ideais de trabalhar com conjuntos de dados alterados, e 
o trabalho da DynamicData é corrigi-lo. Na maioria dos aplicativos, é necessário atualizar dinamicamente as coleções - geralmente, uma coleção é preenchida com alguns elementos quando o aplicativo é iniciado e, em seguida, é atualizada de forma assíncrona, sincronizando informações com um servidor ou banco de dados. As aplicações modernas são bastante complexas e, muitas vezes, é necessário criar projeções de coleções - filtrar, transformar ou classificar elementos. O DynamicData foi projetado apenas para se livrar do código incrivelmente complexo que precisaríamos para gerenciar conjuntos de dados dinamicamente alterados. A ferramenta é ativamente desenvolvida e finalizada, e agora são suportados mais de 60 operadores para trabalhar com coleções.
 DynamicData
DynamicData não é uma implementação alternativa de 
ObservableCollection<T> . A arquitetura 
DynamicData é baseada principalmente nos conceitos de programação específica de domínio. A ideologia de uso é baseada no fato de você gerenciar algumas fontes de dados, uma coleção à qual o código responsável pela sincronização e alteração de dados tem acesso. Em seguida, você aplica vários operadores à origem, com os quais é possível transformar declarativamente os dados, sem a necessidade de criar e modificar manualmente outras coleções. De fato, com o 
DynamicData, você separa as operações de leitura e gravação e só pode ler de maneira reativa - portanto, as coleções herdadas sempre serão sincronizadas com a fonte.
Em vez do 
IObservable<T> clássico 
IObservable<T> , DynamicData define operações em 
IObservable<IChangeSet<T>>> e 
IObservable<IChangeSet<TValue, TKey>> , em que 
IChangeSet é um bloco contendo informações sobre a alteração da coleção - o tipo de alteração e os elementos afetados. Essa abordagem pode melhorar significativamente o desempenho do código para trabalhar com coleções gravadas em um estilo reativo. Ao mesmo tempo, 
IObservable<IChangeSet<T>> sempre pode ser transformado em um 
IObservable<IEnumerable<T>> regular, se for necessário processar todos os elementos da coleção de uma só vez. Se parecer complicado - não se assuste, a partir dos exemplos de código tudo ficará claro e transparente!
Exemplo de DynamicData
Vejamos uma série de exemplos para entender melhor como o DynamicData funciona, como ele difere do 
System.Reactive e quais tarefas os desenvolvedores comuns de software de aplicativo com uma GUI podem resolver. Vamos começar com um exemplo abrangente 
publicado por DynamicData no GitHub . No exemplo, a fonte de dados é 
SourceCache<Trade, long> , que contém uma coleção de transações. A tarefa é mostrar apenas transações ativas, transformar modelos em objetos proxy, classificar a coleção.
 
No exemplo acima, quando você altera o 
SourceCache , que é a fonte de dados, o 
ReadOnlyObservableCollection também muda de acordo. Nesse caso, ao excluir elementos da coleção, o método 
Dispose será chamado, a coleção sempre será atualizada apenas no fluxo da GUI e permanecerá classificada e filtrada. Legal, não 
Dispatcher.Invoke e código complicado!
Fontes de dados SourceList e SourceCache
O DynamicData fornece duas coleções especializadas que podem ser usadas como uma fonte de dados mutável. Essas coleções são dos tipos 
SourceList e 
SourceCache<TObject, TKey> . É recomendável usar o 
SourceCache sempre que o 
TObject tiver uma chave exclusiva; caso contrário, use o 
SourceList . Esses objetos fornecem a familiar API de desenvolvedores .NET para modificar dados - 
Add , 
Remove , 
Insert e similares. Para converter fontes de dados em 
IObservable<IChangeSet<T>> ou 
IObservable<IChangeSet<T, TKey>> , use o operador 
.Connect() . Por exemplo, se você tiver um serviço que atualize a coleção de elementos em segundo plano, poderá sincronizar facilmente a lista desses elementos com a GUI, sem 
Dispatcher.Invoke Invoque excessos arquitetônicos e:
 public class BackgroundService : IBackgroundService {  
O DynamicData usa tipos .NET internos para mapear dados para o mundo externo. Usando os poderosos operadores DynamicData, podemos transformar o 
IObservable<IChangeSet<Trade>> em 
ReadOnlyObservableCollection nosso modelo de exibição.
 public class TradesViewModel : ReactiveObject { private readonly ReadOnlyObservableCollection<TradeVm> _trades; public ReadOnlyObservableCollection<TradeVm> Trades => _trades; public TradesViewModel(IBackgroundService background) {  
Além de 
Transform , 
Filter and 
Sort , o DynamicData inclui uma série de outros operadores, suporta operações lógicas de agrupamento, suaviza uma coleção, utiliza funções agregadas, excluindo elementos idênticos, contando elementos e até virtualizando no nível do modelo de representação. Leia mais sobre todos os operadores no 
projeto README no GitHub .

Coleções únicas e rastreamento de alterações
Além de 
SourceList e 
SourceCache , a biblioteca DynamicData também inclui uma implementação de thread único de uma coleção mutável - 
ObservableCollectionExtended . Para sincronizar duas coleções no seu modelo de exibição, declare uma como 
ObservableCollectionExtended e a outra como 
ReadOnlyObservableCollection e use o operador 
ToObservableChangeSet , que se comporta da mesma forma que o 
Connect mas foi projetado para funcionar com o 
ObservableCollection .
 
O DynamicData também oferece suporte ao rastreamento de alterações nas classes que implementam a interface 
INotifyPropertyChanged . Por exemplo, se você deseja ser notificado de uma alteração na coleção sempre que a propriedade de um item for alterada, use a 
AutoRefresh e passe o seletor da propriedade desejada com o argumento 
AutoRefesh e outros operadores DynamicData permitirão que você valide fácil e naturalmente o grande número de formulários e subformulários exibidos na tela!
 
Com base na funcionalidade DynamicData, você pode criar rapidamente interfaces bastante complexas - isso é especialmente verdadeiro para sistemas que exibem uma grande quantidade de dados em tempo real, sistemas de mensagens instantâneas e sistemas de monitoramento.

Conclusão
As extensões reativas são uma ferramenta poderosa que permite trabalhar declarativamente com dados e a interface do usuário, escrever códigos portáteis e compatíveis e resolver problemas complexos de uma maneira simples e elegante. 
O ReactiveUI permite que os desenvolvedores .NET integrem estreitamente extensões reativas em seus projetos usando a arquitetura MVVM, fornecendo implementações reativas de 
INotifyPropertyChanged e 
ICommand , enquanto 
DynamicData cuida da sincronização de coleções implementando 
INotifyCollectionChanged , expandindo os recursos de extensões reativas e cuidando do desempenho.
As 
bibliotecas ReactiveUI e 
DynamicData são compatíveis com as estruturas de GUI mais populares da plataforma .NET, incluindo o Windows Presentation Foundation, Universal Windows Platform, 
Avalonia , Xamarin.Android, Xamarin Forms, Xamarin.iOS. Você pode começar a aprender DynamicData na 
página de documentação correspondente do ReactiveUI . Verifique também o projeto 
DynamicData Snippets , que contém exemplos de uso do DynamicData para todas as ocasiões.