开发者

Reactive Extensions... Examples in CRUD application

I am just coming to grips with Reactive Extensions but still haven't had that "A-Ha" moment, the moment when it all seems to fit into place. As a result of this, I need some help and want to know what kind of a role reactive extensions might have in a simple CRUD program.

Does anyone have any examples how RX extensions has helped in their CRUD application. As you can imagine I am writing a CRUD application in C# ... any examples are accepted and this is posted so that I can think about how RX might fit into the ty开发者_StackOverflowpe of programming that I am doing.

Perhaps you might list how a programming task has benefited from RX and how the task was being accomplished prior to the use of RX.


I have done this kind of thing that has worked well:

public interface IStorage : IDisposable
{
    IObservable<int> GetOperationsCount(IScheduler scheduler);

    IObservable<Node> FetchNodes(IObservable<NodeId> nodeIds, IScheduler scheduler);
    IObservable<Node> StoreNodes(IObservable<Node> nodes, IScheduler scheduler);
}

It allows me to perform a fetches and stores on a background thread and have values returned to me on the UI thread quite easily.

Each call to StoreNodes also sets up a transaction and I can get any errors from the return observable.

I also use the GetOperationsCount observable to display to the user the number of pending operations, etc.

My personal experience with Rx has made me want to use it for anything asynchronous at all - events, begin/end invoke, async, tasks, thread, etc. It makes everything fit under one model and can be a significant code saver.


if you do static CRUD (get a window/dialog with create, read, update, write, whatever) then I guess it might only help you on your UI. For example, maybe you want some kind of AutoCompletion of certain inputs. Or you have to query a service for additional info to show. Then RX can help you do this. It will hide many async-realated difficulties and gives you readable, declerative expressions you can easily read and quickly do. In this sense it's just the same as LINQ only for UI/async


A typical CRUD application have some UI (winform, WPF etc) and a data store to fetch data and show in the UI. The data flow between these two components (UI and data store) can be modeled using Rx.

Using Rx we can connect the 2 components (UI and data store) such as: UI can exposes 3 observable for Create, Update and Delete (ex: which are passed in the constructor to data store). For ex: The Submit button event can be mapped to generate Create observable values and similarly for Update and delete. So basically the data store needs to subscribe to these 3 observable and doesn't need to bother how the data is generated (this will also help in UT as you can create fake observable easily).

Read would be a simple read method on data store as that is about pulling data on demand.

So basically Rx has worked as a abstraction to compose the 2 components.


Maybe I am wrong, consider the two answers. MS tends to divide their bussiness into to many layers, because they have an interest here.

CRUD is the physical implementation - Create - Read - ... But UI seems to be logical - in the context - for the user ...

Sometimes you need to have a layer - bussiness layer - that controls the flow to and from RDMS. Imo this is very complex.

In finance business the "update" or "delete" action is a replication of the current row with a new timestamp. This makes it difficult to have a clean operation - physical at least ... And on top of all this yout might consider that CRUD is just a part of a transaction - making "a logical unit of work" in flight until all is ok - then you should do a COMMIT.

Hope this will help ...


A CRUD app will have some sort of search functionality. You could implement a textbox search with "type and wait to search" just like in my demo that I recently wrote on my blog :

http://blog.andrei.rinea.ro/2013/06/01/bing-it-on-reactive-extensions-story-code-and-slides/

Essentially using Throttle and other Reactive Extensions you can create a quick search feature.


Rx is great for collections. Right now, I can't imagine working with a language that doesn't have LINQ like functionality.

Recently, it became the same for Rx, mostly because of a library that uses Rx for LINQ: DynamicData

ReadOnlyObservableCollection<TradeProxy> list;

var myTradeCache = new SourceCache<Trade, long>(trade => trade.Id);
var myOperation = myTradeCache.Connect() 
        .Filter(trade=>trade.Status == TradeStatus.Live) 
        .Transform(trade => new TradeProxy(trade))
        .Sort(SortExpressionComparer<TradeProxy>.Descending(t => t.Timestamp))
        .ObserveOnDispatcher()
        .Bind(out list) 
        .DisposeMany()
        .Subscribe()

Basically, you can create LINQ like queries, that refresh themselves dynamically after any change - new item in the source list (just DTO is enough!), some property change, signal from elsewhere (passed as observable), etc.

You want to display number of entities with a flag? One liner.

You want to display easily display dynamic groups based on property chosen by user? One liner.

You want to do paging? 3 lines :P

Also, there is a MVVM framework called ReactiveUI - it provides you with a ReactiveCommand and few more tricks.

Among them is binding framework with converters based on lambdas, ability to react in a View to something very specific that happened in your VM, managing activation of view models (like initial command execution, but not in constructor).

You want the login button to be enabled only if user and password are not empty?

Login = ReactiveCommand.CreateFromTask(async () => { /* your async implementation, it can return a value! */}, 
             this.WhenAnyValue(x => x.Username, x => x.Password, (user, psw) => !string.IsNullOrEmpty(user) && !string.IsNullOrEmpty(psw)); // define when the command can execute by providing IObservable<bool>

    Login.Where(x => x == true) // only successful logins, ==true for clarity 
        .InvokeCommand(DisplayMainScreen); // or something

In view you can do:

Login.Where(x => !x).Subscribe(_ =>{ // if login failed, set focus on password and select all text so user can just retype the password
          PasswordBox.SelectAllText(); // can't remember exact methods, but you get the idea
          PasswordBox.SetFocus();
       });

It just becomes very natural for you to make functionality like "When something, do this"

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜