netdaemon icon indicating copy to clipboard operation
netdaemon copied to clipboard

Make AddScopedHaContext public

Open timia2109 opened this issue 10 months ago • 0 comments

Proposed change

I am changing the visibility of the NetDaemon.HassModel.DependencyInjectionSetup.AddScopedHaContext method to public. For building a (web) application where I need to access a lot of HA states I would like to use the HassModel. Currently I'm using this ugly hack that I want to change:

 // Hack: Initialize Hass Model
var extensionType = typeof(DependencyInjectionSetup);
var methodInfo = extensionType.GetMethod("AddScopedHaContext",
    System.Reflection.BindingFlags.NonPublic
    | System.Reflection.BindingFlags.Static
)  ?? throw new Exception("Error injecting Hass Model");

methodInfo.Invoke(null, [builder.Services]);

In some scenarios (like new ASP.NET Core apps) we don't have an `IHostBuilder'. So the current available public method don't work.

To make this work, you also need a IHostedService. This is my example. I could also implement this on the repo with a different extension method:

internal class HassHostedService(
    IOptions<HomeAssistantSettings> options,
    IHomeAssistantRunner haRunner,
    ICacheManager cacheManager,
    ILogger<HassHostedService> logger
) : IHostedService
{
    private CancellationTokenSource _cancellationTokenSource = new();

    public async Task StartAsync(CancellationToken cancellationToken)
    {
        var haSettings = options.Value;

        haRunner.OnConnect.SubscribeAsync(OnConnection);

        _ = haRunner.RunAsync(
             haSettings.Host,
             haSettings.Port,
             haSettings.Ssl,
             haSettings.Token,
             TimeSpan.FromSeconds(10),
             _cancellationTokenSource.Token
        );
    }

    private async Task OnConnection(IHomeAssistantConnection connection)
    {
        logger.LogInformation("Hass Connection initialized");
        await cacheManager.InitializeAsync(_cancellationTokenSource.Token);
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        _cancellationTokenSource.Cancel();
        return Task.CompletedTask;
    }
}

Type of change

  • [ ] Dependency upgrade
  • [ ] Bugfix (non-breaking change which fixes an issue)
  • [ ] New feature (which adds functionality to an existing integration)
  • [ ] Breaking change (fix/feature causing existing functionality to break)
  • [x] Code quality improvements to existing code or addition of tests

Additional information

  • This PR fixes or closes issue: fixes #
  • This PR is related to issue:
  • Link to documentation pull request:

Checklist

  • [x] The code change is tested and works locally.
  • [x] Local tests pass. Your PR cannot be merged unless tests pass
  • [x] There is no commented out code in this PR.
  • [ ] I have followed the [development checklist][dev-checklist] - (Where is the checklist?)
  • [x] The code compiles without warnings (code quality chek)
  • [ ] Tests have been added to verify that the new code works. - (Not required)

If user exposed functionality or configuration variables are added/changed:

timia2109 avatar Apr 01 '24 17:04 timia2109