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

Make options reloadable #95

Closed
Closed
@rynowak

Description

@rynowak

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.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions