Skip to content
This repository has been archived by the owner on Nov 7, 2018. It is now read-only.

Make options reloadable #95

Closed
rynowak opened this issue Nov 3, 2015 · 1 comment
Closed

Make options reloadable #95

rynowak opened this issue Nov 3, 2015 · 1 comment
Assignees
Milestone

Comments

@rynowak
Copy link
Member

rynowak commented Nov 3, 2015

API changes

IReloadOptions NEW

public interface IReloadOptionsManager
{
    IChangeToken GetReloadToken<TOptions>();
    void Reload<TOptions>();
}

IReloadableOptions NEW

public interface IReloadableOptions<T>
{
    T Value { get; }
    IDisposable Subscribe(Action<T> value);
}

Design Summary

With this approach, there's a new type for consumers of options which want the ability to see updates that occur after
application startup.

Consumers can DI the IReloadableOptions<T> and see updates according to three supported patterns:

1.) Get the current value when the component was created (useful for scoped and transient business objects who don't want
to deal with concurrency issues).

public class HomeController
{
    private AppSettings _settings;

    public HomeController(IReloadableOptions<AppSettings> options)
    {
        _settings = options.Value;
    }

    private bool PriceOfGas => _settings.PriceOfGas;
}

This differs from the normal IOptions<T> behavior. Value can change after it is first accessed.

2.) Get the current value each time .Value is called. Useful when you want realtime updates, but don't have a complicated
set of concurrency behaviors to deal with.

public class HomeController
{
    private IReloadableOptions<AppSettings> _options;

    public HomeController(IReloadableOptions<AppSettings> options)
    {
        _options = options;
    }

    private bool PriceOfGas => _options.Value.PriceOfGas;
}

3.) Be notified when the value changes. Useful for long-lived components that was to recompute data when options change.

public class ProductPriceService : IDisposable
{
    private AppSettings _settings;
    private IDisposable _subscription;

    public ProductPriceService(IReloadableOptions<AppSettings> options)
    {
        _subscription = options.Subscribe(s => _settings = s);
    }

    private bool PriceOfGas => _settings.PriceOfGas;

    public void Dispose()
    {
        _subscription?.Dispose();
    }
}

When using this pattern you WILL LEAK if you don't unregister your callback. The callback is called immediately and
the surrounding object needs to be prepared to deal with that case.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants