From c1d4ffe58c011eca54e7d4552a3adb9ce1bfc611 Mon Sep 17 00:00:00 2001 From: Frank Bakker Date: Tue, 1 Feb 2022 08:51:26 +0100 Subject: [PATCH 1/4] Filter focus apps only in Development environment --- .../Extensions/ServiceCollectionExtension.cs | 1 + .../Internal/AppModelContext.cs | 41 ++++++------------- .../Internal/FocusFilter.cs | 38 +++++++++++++++++ 3 files changed, 52 insertions(+), 28 deletions(-) create mode 100644 src/AppModel/NetDaemon.AppModel/Internal/FocusFilter.cs diff --git a/src/AppModel/NetDaemon.AppModel/Common/Extensions/ServiceCollectionExtension.cs b/src/AppModel/NetDaemon.AppModel/Common/Extensions/ServiceCollectionExtension.cs index 84e813b61..cfefde706 100644 --- a/src/AppModel/NetDaemon.AppModel/Common/Extensions/ServiceCollectionExtension.cs +++ b/src/AppModel/NetDaemon.AppModel/Common/Extensions/ServiceCollectionExtension.cs @@ -122,6 +122,7 @@ private static IServiceCollection AddAppModelIfNotExist(this IServiceCollection .AddSingleton(s => s.GetRequiredService()) .AddTransient() .AddTransient(s => s.GetRequiredService()) + .AddTransient() .AddScopedConfigurationBinder() .AddScopedAppServices() .AddConfigManagement(); diff --git a/src/AppModel/NetDaemon.AppModel/Internal/AppModelContext.cs b/src/AppModel/NetDaemon.AppModel/Internal/AppModelContext.cs index cd2b138ae..3a262967c 100644 --- a/src/AppModel/NetDaemon.AppModel/Internal/AppModelContext.cs +++ b/src/AppModel/NetDaemon.AppModel/Internal/AppModelContext.cs @@ -1,5 +1,5 @@ +using System.Reflection; using NetDaemon.AppModel.Internal.AppFactoryProviders; -using IAppFactory = NetDaemon.AppModel.Internal.AppFactories.IAppFactory; namespace NetDaemon.AppModel.Internal; @@ -9,54 +9,39 @@ internal class AppModelContext : IAppModelContext, IAsyncInitializable private readonly IEnumerable _appFactoryProviders; private readonly IServiceProvider _provider; + private readonly FocusFilter _focusFilter; private bool _isDisposed; - public AppModelContext(IEnumerable appFactoryProviders, IServiceProvider provider) + public AppModelContext(IEnumerable appFactoryProviders, IServiceProvider provider, FocusFilter focusFilter) { _appFactoryProviders = appFactoryProviders; _provider = provider; + _focusFilter = focusFilter; } public IReadOnlyCollection Applications => _applications; - public async ValueTask DisposeAsync() - { - if (_isDisposed) - return; - - foreach (var appInstance in _applications) await appInstance.DisposeAsync().ConfigureAwait(false); - _applications.Clear(); - _isDisposed = true; - } - public async Task InitializeAsync(CancellationToken cancellationToken) { - await LoadApplications(); - } + var factories = _appFactoryProviders.SelectMany(provider => provider.GetAppFactories()).ToList(); - private async Task LoadApplications() - { - var factories = GetAppFactories().ToList(); - var loadOnlyFocusedApps = ShouldLoadOnlyFocusedApps(factories); + var filterdFactories = _focusFilter.FilterFocusApps(factories); - foreach (var factory in factories) + foreach (var factory in filterdFactories) { - if (loadOnlyFocusedApps && !factory.HasFocus) - continue; // We do not load applications that does not have focus attr and we are in focus mode - var app = ActivatorUtilities.CreateInstance(_provider, factory); await app.InitializeAsync().ConfigureAwait(false); _applications.Add(app); } } - private IEnumerable GetAppFactories() + public async ValueTask DisposeAsync() { - return _appFactoryProviders.SelectMany(provider => provider.GetAppFactories()); - } + if (_isDisposed) + return; - private static bool ShouldLoadOnlyFocusedApps(IEnumerable factories) - { - return factories.Any(factory => factory.HasFocus); + foreach (var appInstance in _applications) await appInstance.DisposeAsync().ConfigureAwait(false); + _applications.Clear(); + _isDisposed = true; } } \ No newline at end of file diff --git a/src/AppModel/NetDaemon.AppModel/Internal/FocusFilter.cs b/src/AppModel/NetDaemon.AppModel/Internal/FocusFilter.cs new file mode 100644 index 000000000..8cb776298 --- /dev/null +++ b/src/AppModel/NetDaemon.AppModel/Internal/FocusFilter.cs @@ -0,0 +1,38 @@ +using Microsoft.Extensions.Hosting; +using NetDaemon.AppModel.Internal.AppFactories; + +namespace NetDaemon.AppModel.Internal; + +class FocusFilter +{ + private readonly ILogger _logger; + private readonly IHostEnvironment _hostEnvironment; + + public FocusFilter(ILogger logger, IHostEnvironment hostEnvironment) + { + _logger = logger; + _hostEnvironment = hostEnvironment; + } + + public IReadOnlyCollection FilterFocusApps(IReadOnlyCollection allApps) + { + var focusApps = allApps.Where(a => a.HasFocus).ToList(); + + if (focusApps.Count == 0) return allApps; + + foreach (var focusApp in focusApps) + { + _logger.LogInformation("[Focus] attribute is set for app {AppName}", focusApp.Id); + } + + if (!_hostEnvironment.IsDevelopment()) + { + _logger.LogError("{Count} Focus apps were found but current environment is not 'Development', the [Focus] attribute is ignored" + + "Make sure the environment variable `DOTNET_ENVIRONMENT` is set to `Development` to use [Focus] or remove the [Focus] attribute when running in production", focusApps.Count); + return allApps; + } + + _logger.LogWarning($"Found {focusApps.Count} [Focus] apps, skipping all other apps"); + return focusApps; + } +} \ No newline at end of file From 803842cbc347432cddeb4597d39fbecd61cea839 Mon Sep 17 00:00:00 2001 From: Frank Bakker Date: Tue, 1 Feb 2022 10:11:02 +0100 Subject: [PATCH 2/4] Update src/AppModel/NetDaemon.AppModel/Internal/AppModelContext.cs Co-authored-by: BeeHiveJava --- src/AppModel/NetDaemon.AppModel/Internal/AppModelContext.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AppModel/NetDaemon.AppModel/Internal/AppModelContext.cs b/src/AppModel/NetDaemon.AppModel/Internal/AppModelContext.cs index 3a262967c..c2afd7566 100644 --- a/src/AppModel/NetDaemon.AppModel/Internal/AppModelContext.cs +++ b/src/AppModel/NetDaemon.AppModel/Internal/AppModelContext.cs @@ -25,7 +25,7 @@ public async Task InitializeAsync(CancellationToken cancellationToken) { var factories = _appFactoryProviders.SelectMany(provider => provider.GetAppFactories()).ToList(); - var filterdFactories = _focusFilter.FilterFocusApps(factories); + var filteredFactories = _focusFilter.FilterFocusApps(factories); foreach (var factory in filterdFactories) { From b731a43e9a7c95eebbd3f8ad669064786e5b75b6 Mon Sep 17 00:00:00 2001 From: Frank Bakker Date: Tue, 1 Feb 2022 10:11:07 +0100 Subject: [PATCH 3/4] Update src/AppModel/NetDaemon.AppModel/Internal/AppModelContext.cs Co-authored-by: BeeHiveJava --- src/AppModel/NetDaemon.AppModel/Internal/AppModelContext.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AppModel/NetDaemon.AppModel/Internal/AppModelContext.cs b/src/AppModel/NetDaemon.AppModel/Internal/AppModelContext.cs index c2afd7566..f6fe4938d 100644 --- a/src/AppModel/NetDaemon.AppModel/Internal/AppModelContext.cs +++ b/src/AppModel/NetDaemon.AppModel/Internal/AppModelContext.cs @@ -27,7 +27,7 @@ public async Task InitializeAsync(CancellationToken cancellationToken) var filteredFactories = _focusFilter.FilterFocusApps(factories); - foreach (var factory in filterdFactories) + foreach (var factory in filteredFactories) { var app = ActivatorUtilities.CreateInstance(_provider, factory); await app.InitializeAsync().ConfigureAwait(false); From f6a6cd5f79db1a97982f857c7afb11409def9eda Mon Sep 17 00:00:00 2001 From: Frank Bakker Date: Tue, 1 Feb 2022 11:40:38 +0100 Subject: [PATCH 4/4] Fix test --- src/AppModel/NetDaemon.AppModel.Tests/AppModelTests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/AppModel/NetDaemon.AppModel.Tests/AppModelTests.cs b/src/AppModel/NetDaemon.AppModel.Tests/AppModelTests.cs index cbfe88931..ac2724139 100644 --- a/src/AppModel/NetDaemon.AppModel.Tests/AppModelTests.cs +++ b/src/AppModel/NetDaemon.AppModel.Tests/AppModelTests.cs @@ -255,6 +255,7 @@ public async Task TestFocusShouldAlwaysLoadAppIfIndependentOfStateManager(Applic fakeAppStateManager.Setup(n => n.GetStateAsync(It.IsAny())).ReturnsAsync(() => applicationState); var builder = Host.CreateDefaultBuilder() + .UseEnvironment("Development") .ConfigureServices((_, services) => { services.AddTransient>(