Skip to content

Changing the interface INonGenericStateObserver to be able to manage the state of different StateObserver<T> objects#4

Open
megafetis wants to merge 2 commits into
TheDusty01:mainfrom
megafetis:main
Open

Changing the interface INonGenericStateObserver to be able to manage the state of different StateObserver<T> objects#4
megafetis wants to merge 2 commits into
TheDusty01:mainfrom
megafetis:main

Conversation

@megafetis

Copy link
Copy Markdown
Contributor

Example: creating base blazor component with register state function, and unregister when Dispose

@megafetis

megafetis commented Jan 24, 2025

Copy link
Copy Markdown
Contributor Author

now i have to do this ugly thing:

private ConcurrentBag<INonGenericStateObserver> _states = new();

...

public virtual void Dispose()
{
    _disposeCancellationSource?.Cancel();
    foreach (var item in _states)
    {
        item.GetType().GetMethod("Unregister")!.Invoke(item, [this]);
    }
}

@TheDusty01

Copy link
Copy Markdown
Owner

Will reply soon, thanks for your PR!

@TheDusty01

Copy link
Copy Markdown
Owner

@megafetis could you elaborate on why this is needed? How does the component look like that uses ConcurrentBag<INonGenericStateObserver> _states ?

@megafetis

megafetis commented Feb 3, 2025

Copy link
Copy Markdown
Contributor Author

@megafetis could you elaborate on why this is needed? How does the component look like that uses ConcurrentBag<INonGenericStateObserver> _states ?

my case:
base component, uses state, auto unsubscribes on dispose, and so on.

public abstract class AbstractComponent : ComponentBase, IDisposable
{
    private CancellationTokenSource? _disposeCancellationSource;

    protected CancellationToken DisposeToken => (_disposeCancellationSource??=new()).Token;
    private ConcurrentBag<INonGenericStateObserver> _states = new();

    protected void RegisterState<TState>(IStateObserver<TState> state,Action? callback = null)
    {
        state.Register(this, callback ?? StateHasChanged);
        _states.Add(state);
    }
    
    protected void RegisterState<TState>(IStateObserver<TState> state, Func<Task> callback)
    {
        state.Register(this, callback);
        _states.Add(state);
    }

    public virtual void Dispose()
    {
        _disposeCancellationSource?.Cancel();
        foreach (var item in _states)
        {
            item.GetType().GetMethod("Unregister")!.Invoke(item, [this]);
        }
    }
}

derived:

@page "/me"
@inherits AbstractComponent
<PageTitle>My page</PageTitle>

<SomeCode/>

@code {
    [CascadingParameter]
    private CabinetStore Store { get; set; } = null!;
    
    protected override void OnInitialized()
    {
        this.RegisterState(Store.Notifications);
    }

}

in addition, there is actually a convenient opportunity to make sense of the common interface INonGenericStateObserver, isn't it obvious?

@TheDusty01

Copy link
Copy Markdown
Owner

Thanks for clarifying. I think the AutoState is solving exactly what you're doing but it is only available for Blazor WASM.

Your PR makes sense anyway, we can move those methods to the non generic interface though

@megafetis

megafetis commented Feb 10, 2025

Copy link
Copy Markdown
Contributor Author

Thanks for clarifying. I think the AutoState is solving exactly what you're doing but it is only available for Blazor WASM.

Your PR makes sense anyway, we can move those methods to the non generic interface though

Thanks, I hope the changes will be published. I dont not, but AutoState is not working for me in blazor wasm net8. May be i do something wrong. But I'm fine with managing subscriptions to the state manually.

@megafetis

Copy link
Copy Markdown
Contributor Author

Hello. When do you plan to post updates?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants