Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

theAutomaters


code: its neverending

Lazy Observables

So lately I have been writing a bit of code that uses the IObservable interface and I really think it is quite a hassle to get anything done related to IObservable without Reactive Extensions.

Reactive Extensions provides a ton of useful features but while browsing the code of another project, ReactiveUI, I saw a pattern that I think is very nice which allows you to implement Lazy Observables.

class ClassWithChangedEvent  
{
    Lazy<Subject<int>> _itemAdded;  
    public IObservable<int> ItemAdded { get { return _itemAdded.Value; } }

    public ClassWithChangedEvent()
    {
        _changed = new Lazy<Subject<int>>(() => new Subject<int>());    
    }

    public void AddItem(int item)
    {
        // Do something with item

        // Anounce event (only if its been created)
        if (_itemAdded.IsValueCreated) 
            _itemAdded.Value.OnNext(item);        
    }           
}

The main benefit in the above sample is that the subject wont be created unless ItemAdded is accessed.

I made a small improvement on this by creating the following extension class:

static class LazyObservableExtensions  
{
    public static void OnNext<T>(this Lazy<Subject<T>> subject, T item)
    {
        if (subject.IsValueCreated) 
            subject.Value.OnNext(item);
    }

    public static void OnError<T>(this Lazy<Subject<T>> subject, Exception error)
    {
        if (subject.IsValueCreated) 
            subject.Value.OnError(error);
    }

    public static void OnCompleted<T>(this Lazy<Subject<T>> subject)
    {
        if (subject.IsValueCreated) 
            subject.Value.OnCompleted();
    } 

    public static void Dispose<T>(this Lazy<Subject<T>> subject)
    {
        if (subject.IsValueCreated) 
            subject.Value.Dispose();
    }     
}

Now the original code sample becomes:

class ClassWithChangedEvent  
{
    Lazy<Subject<int>> _itemAdded;  
    public IObservable<int> ItemAdded { get { return _itemAdded.Value; } }

    public ClassWithChangedEvent()
    {
        _changed = new Lazy<Subject<int>>(() => new Subject<int>());    
    }

    public void AddItem(int item)
    {
        // Do something with item

        // Anounce event (only if its been created)
        _itemAdded.OnNext(item);
    }           
}

Now you have a simple way to create Lazy observables.


About the author

Kevin Thompson

Fresno, California Area

I am a software developer that likes to experiment with emerging or interesting technologies.


Discussions

comments powered by Disqus