Dynamic Data is a portable class library which brings the power of Reactive Extensions (Rx) to collections.
Mutable collections frequently experience additions, updates, and removals (among other changes). Dynamic Data provides two collection implementations, an observable list and an observable cache that expose changes to the collection via an observable change set. The resulting observable change sets can be manipulated and transformed using Dynamic Data’s robust and powerful array of change set operators. These operators receive change notifications, apply some logic, and subsequently provide their own change notifications. Because of this, operators are fully composable and can be chained together to perform powerful and very complicated operations while maintaining simple, fluent code.
Using Dynamic Data’s collections and change set operators make in-memory data management extremely easy and can reduce the size and complexity of your code base by abstracting complicated and often repetitive collection based operations.
An example please
Given a Trade object create an observable list like this
var myTrades = new SourceList<Trade>();
or a cache which requires that a unique key is specified
var myTrades = new SourceCache<Trade,long>(trade => trade.Id);
Either of these collections are made observable by calling the Connect()
method which produces an observable change set.
var myObservableTrades = myTrades.Connect();
This example first filters a stream of trades to select only live trades, then creates a proxy for each live trade, and finally orders the results by most recent first. The resulting trade proxies are bound on the dispatcher thread to the specified observable collection.
ReadOnlyObservableCollection<TradeProxy> data;
var loader = myObservableTrades
.Filter(trade => trade.Status == TradeStatus.Live) //filter on live trades only
.Transform(trade => new TradeProxy(trade)) //create a proxy
.Sort(SortExpressionComparer<TradeProxy>.Descending(t => t.Timestamp))
.ObserveOnDispatcher() //ensure operation is on the UI thread
.Bind(out data) //Populate the observable collection
.DisposeMany() //Dispose TradeProxy when no longer required
.Subscribe();
Since the TradeProxy object is disposable, the DisposeMany
operator ensures that the proxy objects are disposed when they are no longer part of this observable stream.
This is the tip of the iceberg. The observable cache over 60 operators and the observable list has around 35 operators and counting.
Want to find out more?
Read the following for a quick overview
1. Observable Cache at a glance
2. Observable List at a glance
3. Getting Started
4. Binding example
Download the demo and source code
1. Demo WPF trading system demo on GitHub
2. Demo WPF reactive tree demo on GitHub
3. Dynamic Data source code on GitHub
Some funky UI specific stuff
1. Dynamically filter, sort and page
2. Reactive Tree
3. Advanced search hints with logical collection operators
4. Aggregation of dynamic data
Work through the ‘Creating a trading system’ series
1. Expose the data as a service
2. Manage market data
3. Integration with the UI
4. Filter on calculated values
5. Aggregation of dynamic data
Example integration with ReactiveUI
1. Integration with ReactiveUI for a simple example.
2. Log entry viewer for an advanced example.
Install from Nuget
1. Dynamic Data
or 2. Dynamic Data Adaptors for Reactive UI if you are already using ReactiveUI