Skip to content

Use dependency injection instead of navigation parameter #3311

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 16, 2025

Conversation

Jack251970
Copy link
Contributor

Follow on with #3310.

We should use dependency injection instead of navigation parameter to get instances.

Copy link

gitstream-cm bot commented Mar 5, 2025

🥷 Code experts: Yusyuriv, onesounds

Jack251970 has most 👩‍💻 activity in the files.
Yusyuriv, onesounds have most 🧠 knowledge in the files.

See details

Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml.cs

Activity based on git-commit:

Jack251970
MAR
FEB
JAN
DEC
NOV
OCT

Knowledge based on git-blame:
Yusyuriv: 69%
onesounds: 31%

Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml.cs

Activity based on git-commit:

Jack251970
MAR
FEB
JAN
DEC
NOV
OCT

Knowledge based on git-blame:
Yusyuriv: 54%
onesounds: 46%

Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs

Activity based on git-commit:

Jack251970
MAR
FEB
JAN
DEC
NOV
OCT

Knowledge based on git-blame:
Yusyuriv: 57%
onesounds: 43%

Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml.cs

Activity based on git-commit:

Jack251970
MAR
FEB 1 additions & 2 deletions
JAN
DEC
NOV
OCT

Knowledge based on git-blame:
Yusyuriv: 80%
onesounds: 18%

Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml.cs

Activity based on git-commit:

Jack251970
MAR
FEB
JAN
DEC
NOV
OCT

Knowledge based on git-blame:
Yusyuriv: 63%
onesounds: 37%

Flow.Launcher/SettingPages/Views/SettingsPaneProxy.xaml.cs

Activity based on git-commit:

Jack251970
MAR
FEB
JAN
DEC
NOV
OCT

Knowledge based on git-blame:
Yusyuriv: 58%
onesounds: 42%

Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml.cs

Activity based on git-commit:

Jack251970
MAR
FEB
JAN
DEC
NOV
OCT

Knowledge based on git-blame:
Yusyuriv: 79%
onesounds: 21%

Flow.Launcher/SettingWindow.xaml.cs

Activity based on git-commit:

Jack251970
MAR
FEB
JAN 14 additions & 8 deletions
DEC
NOV 22 additions & 2 deletions
OCT

Knowledge based on git-blame:
Yusyuriv: 53%
onesounds: 11%

To learn more about /:\ gitStream - Visit our Docs

Copy link

github-actions bot commented Mar 5, 2025

@check-spelling-bot Report

🔴 Please review

See the 📂 files view, the 📜action log, or 📝 job summary for details.

❌ Errors Count
❌ forbidden-pattern 22
⚠️ ignored-expect-variant 1
⚠️ non-alpha-in-dictionary 19

See ❌ Event descriptions for more information.

If the flagged items are 🤯 false positives

If items relate to a ...

  • binary file (or some other file you wouldn't want to check at all).

    Please add a file path to the excludes.txt file matching the containing file.

    File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.

    ^ refers to the file's path from the root of the repository, so ^README\.md$ would exclude README.md (on whichever branch you're using).

  • well-formed pattern.

    If you can write a pattern that would match it,
    try adding it to the patterns.txt file.

    Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.

    Note that patterns can't match multiline strings.

Copy link

gitstream-cm bot commented Mar 5, 2025

Be a legend 🏆 by adding a before and after screenshot of the changes you made, especially if they are around UI/UX.

Copy link
Contributor

coderabbitai bot commented Mar 5, 2025

📝 Walkthrough

Walkthrough

The pull request streamlines the initialization logic in several settings pane classes of Flow.Launcher by replacing conditional checks on navigation data with direct dependency injection. The changes remove error handling associated with missing data by utilizing Ioc.Default.GetRequiredService<>() for service retrieval. In addition, redundant fields and a record in the main Settings window (related to Updater and IPortable) have been removed to simplify navigation.

Changes

File(s) Change Summary
Flow.Launcher/.../SettingsPaneAbout.xaml.cs
Flow.Launcher/.../SettingsPaneGeneral.xaml.cs
Flow.Launcher/.../SettingsPaneHotkey.xaml.cs
Flow.Launcher/.../SettingsPanePluginStore.xaml.cs
Flow.Launcher/.../SettingsPanePlugins.xaml.cs
Flow.Launcher/.../SettingsPaneProxy.xaml.cs
Flow.Launcher/.../SettingsPaneTheme.xaml.cs
Removed conditional checks for validating extra navigation data; replaced with direct dependency injection via Ioc.Default.GetRequiredService<>(). Updated using directives to include CommunityToolkit.Mvvm.DependencyInjection and related modules.
Flow.Launcher/SettingWindow.xaml.cs Removed private fields (_updater, _portable) and the associated PaneData record. Simplified the navigation logic by eliminating the need to pass data between components during page transitions.

Sequence Diagram(s)

sequenceDiagram
    participant SW as SettingWindow
    participant SP as SettingsPane (Any)
    participant DI as Ioc Container
    SW->>SP: Navigate (no extra data)
    SP->>DI: GetRequiredService<Settings>()
    DI-->>SP: Return Settings
    SP->>DI: GetRequiredService<Updater>() (if needed)
    DI-->>SP: Return Updater
    SP->>SP: Initialize ViewModel
Loading

Possibly related PRs

Suggested labels

enhancement, kind/ui

Suggested reviewers

  • jjw24
  • taooceros

Poem

Oh, how I hop through lines of code,
Dependency injections lighten my load.
Gone are checks that used to scare,
Now services appear with flair.
I’m a coding bunny, quick and free,
Cheering for a simpler flow with glee!
🐇💻

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (9)
Flow.Launcher/SettingWindow.xaml.cs (1)

161-166: Improved code through dependency injection.

The code is now using dependency injection instead of passing data through navigation parameters. This is a cleaner approach as it decouples the pages from their data sources.

While the current implementation works well, consider adding a comment explaining the dependency injection pattern for future maintainers:

 if (args.IsSettingsSelected)
 {
     ContentFrame.Navigate(typeof(SettingsPaneGeneral));
+    // Note: SettingsPaneGeneral retrieves its dependencies via IoC.Default.GetRequiredService<>()
 }
Flow.Launcher/SettingPages/Views/SettingsPaneProxy.xaml.cs (1)

13-25: Consider implementing constructor injection for better testability.

While using the service locator pattern with Ioc.Default.GetRequiredService<>() is an improvement over manual parameter checking, constructor injection would be even better for testability. The current approach with direct static IoC access can make unit testing more challenging.

Consider refactoring to use constructor injection:

public partial class SettingsPaneProxy
{
-   private SettingsPaneProxyViewModel _viewModel = null!;
+   private readonly Settings _settings;
+   private readonly Updater _updater;
+   private SettingsPaneProxyViewModel _viewModel = null!;

+   public SettingsPaneProxy()
+   {
+       _settings = Ioc.Default.GetRequiredService<Settings>();
+       _updater = Ioc.Default.GetRequiredService<Updater>();
+   }

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        if (!IsInitialized)
        {
-           var settings = Ioc.Default.GetRequiredService<Settings>();
-           var updater = Ioc.Default.GetRequiredService<Updater>();
-           _viewModel = new SettingsPaneProxyViewModel(settings, updater);
+           _viewModel = new SettingsPaneProxyViewModel(_settings, _updater);
            DataContext = _viewModel;
            InitializeComponent();
        }

        base.OnNavigatedTo(e);
    }
}

This approach would move the dependency resolution to the constructor, making it easier to substitute dependencies in tests.

Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml.cs (1)

18-18: Good refactoring to use dependency injection.

Replacing the previous parameter-based approach with dependency injection is a positive architectural change. This modification:

  1. Decouples components by removing direct dependencies on navigation parameters
  2. Makes the code more testable (services can be mocked more easily)
  3. Centralizes dependency management
  4. Better follows SOLID principles, particularly the Dependency Inversion Principle

The use of GetRequiredService is appropriate here as it follows the fail-fast principle - if the service isn't registered, it will throw an exception immediately rather than causing issues later.

Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml.cs (1)

17-18: Clean implementation of dependency injection pattern.

The change from extracting services from navigation parameters to directly retrieving them from the IoC container improves the code by:

  1. Reducing coupling between navigation and service dependencies
  2. Making the dependencies more explicit
  3. Simplifying the initialization flow by removing conditional checks and explicit error handling

This approach aligns with modern dependency injection practices and makes the code more maintainable and testable.

Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs (1)

16-16: Excellent switch to dependency injection.

This change effectively implements the PR's objective by replacing navigation parameter usage with proper dependency injection. This approach is more maintainable and decouples the component from the navigation mechanism.

This dependency injection pattern:

  • Improves testability as services can be easily mocked during testing
  • Reduces coupling between components
  • Makes dependencies explicit and reduces "magic" navigation parameters
  • Simplifies the component initialization process
Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml.cs (2)

20-20: Unused variable detected.

The settings variable is retrieved but not used in the method. Consider removing it if it's not needed, or ensure it's being used where intended.

-var settings = Ioc.Default.GetRequiredService<Settings>();

If the variable is actually needed elsewhere in the code (perhaps in the ViewModel constructor), please make that clear.


16-27: Consider adding error handling for DI service resolution.

When using GetRequiredService<T>(), if the service is not registered, it will throw an exception that may be less specific than the previous ArgumentException. Consider adding a try-catch block with a more descriptive error message to maintain the same level of error reporting.

if (!IsInitialized)
{
    try
    {
        var settings = Ioc.Default.GetRequiredService<Settings>();
        _viewModel = new SettingsPanePluginStoreViewModel();
        DataContext = _viewModel;
        InitializeComponent();
    }
    catch (InvalidOperationException ex)
    {
        throw new InvalidOperationException("Failed to resolve Settings service. Ensure it is registered properly in the IoC container.", ex);
    }
}
Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml.cs (1)

18-20: Excellent implementation of dependency injection pattern

This change effectively implements the dependency injection pattern to retrieve required services instead of relying on navigation parameters. This approach offers several benefits:

  1. More maintainable and testable code
  2. Clear declaration of dependencies
  3. Reduced coupling between components
  4. Consistent with modern software design principles

The use of GetRequiredService<>() is appropriate here as these are essential dependencies that should fail fast if not available.

Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml.cs (1)

13-23: Consider extracting initialization logic to a separate method

The current implementation mixes navigation handling with component initialization. For improved readability and maintainability, consider extracting the initialization logic into a dedicated method.

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    if (!IsInitialized)
    {
-       var settings = Ioc.Default.GetRequiredService<Settings>();
-       _viewModel = new SettingsPanePluginsViewModel(settings);
-       DataContext = _viewModel;
-       InitializeComponent();
+       InitializeViewModel();
    }
    base.OnNavigatedTo(e);
}

+private void InitializeViewModel()
+{
+    var settings = Ioc.Default.GetRequiredService<Settings>();
+    _viewModel = new SettingsPanePluginsViewModel(settings);
+    DataContext = _viewModel;
+    InitializeComponent();
+}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a4111ae and 31d47a2.

📒 Files selected for processing (8)
  • Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml.cs (2 hunks)
  • Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml.cs (2 hunks)
  • Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs (2 hunks)
  • Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml.cs (2 hunks)
  • Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml.cs (2 hunks)
  • Flow.Launcher/SettingPages/Views/SettingsPaneProxy.xaml.cs (2 hunks)
  • Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml.cs (2 hunks)
  • Flow.Launcher/SettingWindow.xaml.cs (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: gitStream.cm
🔇 Additional comments (17)
Flow.Launcher/SettingWindow.xaml.cs (1)

176-188: Clean migration to dependency injection.

The removal of navigation parameters across all page navigations creates a consistent pattern throughout the application. This change implements the PR objective of replacing navigation parameters with dependency injection.

The code is now more maintainable as each settings pane is responsible for acquiring its own dependencies rather than relying on the parent window to provide them.

Flow.Launcher/SettingPages/Views/SettingsPaneProxy.xaml.cs (2)

1-6: Good update to the import statements.

The import statements have been appropriately updated to include the necessary dependencies for IoC and removed unnecessary imports.


17-18: Appropriate implementation of dependency injection.

The change from checking navigation parameters to using dependency injection is a good improvement that:

  1. Decouples the component from the navigation mechanism
  2. Simplifies the initialization logic
  3. Removes error-prone parameter validation code

This approach aligns with modern best practices for dependency management.

Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml.cs (2)

3-3: Good addition of dependency injection infrastructure.

These import statements are necessary to support the transition from navigation parameters to dependency injection. The CommunityToolkit.Mvvm.DependencyInjection namespace provides the IoC container capabilities needed for the new approach.

Also applies to: 6-6


1-32:

✅ Verification successful

Overall well-implemented dependency injection pattern.

The removal of navigation parameter handling and the shift to dependency injection is consistent with modern software design principles. This change simplifies the code, removes conditional checks, and makes the component more maintainable.

Since this appears to be part of a broader refactoring effort (as mentioned in the PR objectives), it's important to verify that this pattern is being consistently applied across all similar components, which seems to be the case from the PR summary.


🏁 Script executed:

#!/bin/bash
# Check if dependency injection is applied consistently across other settings panes

echo "Checking other settings panes for consistent dependency injection pattern..."
rg -l "GetRequiredService<Settings>" --type cs Flow.Launcher/SettingPages/Views/

Length of output: 669


Dependency injection implementation is consistent and effective.

The refactoring in Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml.cs—specifically, the removal of navigation parameter handling in favor of dependency injection—is well executed. A search across other settings pages confirms that this dependency injection pattern is consistently applied throughout the module (e.g., in SettingsPanePlugins.xaml.cs, SettingsPaneProxy.xaml.cs, etc.). This approach improves code clarity and maintainability in line with modern software design principles.

Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml.cs (2)

1-5: Properly organized imports for dependency injection.

The new imports enable the dependency injection approach, replacing the previous navigation parameter method. The CommunityToolkit.Mvvm.DependencyInjection namespace provides the IoC container functionality needed for service resolution.


13-24:

✅ Verification successful

Verify service registration in the IoC container.

The GetRequiredService<T>() method will throw an exception if the requested service is not registered in the IoC container. Ensure that both Settings and Updater services are properly registered during application startup.


🏁 Script executed:

#!/bin/bash
# Check for service registration in the IoC container setup

# Look for Settings registration
echo "Checking for Settings registration:"
rg "RegisterSingleton\s*<\s*Settings\s*>|Add\w*<\s*Settings\s*>|GetRequiredService\s*<\s*Settings\s*>" --type cs

# Look for Updater registration
echo "Checking for Updater registration:"
rg "RegisterSingleton\s*<\s*Updater\s*>|Add\w*<\s*Updater\s*>|GetRequiredService\s*<\s*Updater\s*>" --type cs

# Check the IoC initialization to confirm these services are registered
echo "Checking IoC initialization:"
rg "Ioc\.Default\.(ConfigureServices|RegisterServices)" --type cs -A 20

Length of output: 4096


Service Registration Verified

The verification confirms that both the Settings and Updater services are registered and retrieved properly throughout the codebase. Their usage in multiple files—including in the IoC container initialization within App.xaml.cs—indicates that the services are appropriately set up during application startup. No changes are required for the code in Flow.Launcher/SettingPages/Views/SettingsPaneAbout.xaml.cs.

Flow.Launcher/SettingPages/Views/SettingsPaneHotkey.xaml.cs (2)

2-2: Good addition of the DI namespace.

Adding the CommunityToolkit DI namespace is necessary for the dependency injection approach being implemented.


12-22:

❓ Verification inconclusive

Verify service registration in the IoC container.

The code now relies on the IoC container to provide the Settings service. While this is a good approach, it's important to ensure that the Settings class is properly registered in the IoC container during application startup.


🏁 Script executed:

#!/bin/bash
# Check if Settings is registered in the IoC container
echo "Checking for Settings registration in IoC container..."

# Look for Settings registration in the application startup code
rg "AddSingleton<Settings>" --type cs
rg "AddTransient<Settings>" --type cs
rg "AddScoped<Settings>" --type cs
rg "RegisterService.*Settings" --type cs
rg "Ioc.*Register.*Settings" --type cs

Length of output: 319


Action Required: Manually Verify IoC Registration for Settings

Our initial automated search for common IoC registration patterns for the Settings service (e.g., AddSingleton<Settings>, AddTransient<Settings>, etc.) did not return any results. This absence could mean one of two things:

  • The Settings service may be registered using a non-standard pattern or in a file/location that wasn’t covered by our search (e.g., custom registration methods).
  • The Settings service might not be registered at all, which will lead to a runtime resolution error in the OnNavigatedTo method.

Please take the following actions:

  • Manually verify the IoC container configuration in your startup files (e.g., Program.cs, App.xaml.cs, or any custom IoC configuration code) to ensure that the Settings service is registered.
  • If the Settings service is registered using a custom approach (such as a dedicated registration helper), please ensure that this pattern is well documented or explicitly referenced in the PR.

After confirming the registration status, update the IoC registration if necessary.

Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml.cs (3)

5-5: Good addition of necessary imports for DI.

These imports support the move to dependency injection for obtaining services.

Also applies to: 8-8


20-20: Effective use of dependency injection.

This change simplifies the code by replacing a conditional check on navigation parameters with a direct service request. This is a good architectural improvement that:

  1. Reduces boilerplate error handling code
  2. Makes the component less dependent on the navigation mechanism
  3. Follows the dependency inversion principle (SOLID)

20-20:

❓ Verification inconclusive

Verify DI service registration exists.

Make sure that Settings is properly registered in the DI container elsewhere in the codebase. Without proper registration, this line will throw an exception at runtime.


🏁 Script executed:

#!/bin/bash
# Search for where Settings is registered in the IoC container
echo "Searching for Settings registration in IoC container..."
rg -l "RegisterSingleton\s*<\s*Settings\s*>" --type cs || rg -l "RegisterType\s*<\s*Settings\s*>" --type cs || rg -l "Register\s*<\s*Settings\s*>" --type cs

# Also search for IoC.Default.Register calls
rg -l "Ioc\.Default\.Register\s*<\s*Settings\s*>" --type cs

# Check for any GetRequiredService usage for Settings to see the pattern
rg -l "GetRequiredService\s*<\s*Settings\s*>" --type cs

Length of output: 988


Action: Confirm DI Registration for Settings

Our search did not reveal any explicit DI container registration for the Settings service using the typical patterns (e.g., RegisterSingleton<Settings>, RegisterType<Settings>, or Ioc.Default.Register<Settings>). However, several files are invoking GetRequiredService<Settings>, which implies that registration is expected.

  • Please verify that Settings is registered through an alternative mechanism (such as auto-registration, a custom startup routine, or reflection-based scanning) in your application's initialization code.
  • Ensure that registration occurs before any calls to GetRequiredService<Settings> to avoid potential exceptions at runtime.
  • Consider documenting or adding a unit test to confirm that the DI container is properly populating the Settings dependency.
Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml.cs (2)

2-4: Good addition of required namespaces

The newly added namespaces properly support the dependency injection implementation.


14-26:

❓ Verification inconclusive

Verify initialization timing in the DI container

The refactoring assumes that all required services (Settings, Updater, and Portable) are registered in the IoC container before this component is navigated to. Ensure that the container initialization happens early in the application lifecycle to prevent runtime exceptions.

Additionally, since you're now using required services that will throw exceptions if not found, consider adding exception handling or verifying through integration tests that these services are always properly registered before navigation.


🏁 Script executed:

#!/bin/bash
# Check how the IoC container is initialized and where these services are registered

# 1. Look for IoC container initialization
echo "Searching for IoC container initialization..."
rg -A 5 "Ioc\.Default\.ConfigureServices|AddSingleton|AddTransient|AddScoped" --glob "*.cs"

# 2. Look specifically for registration of the three used services
echo -e "\nSearching for Settings service registration..."
rg "AddSingleton<Settings>|AddSingleton<.*Settings>|AddSingleton\(.*typeof\(Settings\)" --glob "*.cs"

echo -e "\nSearching for Updater service registration..."
rg "AddSingleton<Updater>|AddSingleton<.*Updater>|AddSingleton\(.*typeof\(Updater\)" --glob "*.cs"

echo -e "\nSearching for Portable service registration..."
rg "AddSingleton<Portable>|AddSingleton<.*Portable>|AddSingleton\(.*typeof\(Portable\)" --glob "*.cs"

Length of output: 2329


Verify DI Service Initialization and Enhance Resilience

The IoC container is initialized early in the application lifecycle (as seen in Flow.Launcher/App.xaml.cs), and the required services are registered:

  • Settings: Registered via a lambda (.AddSingleton(_ => _settings)), so ensure that _settings is indeed an instance of the Settings type.
  • Updater: Registered using a factory method (.AddSingleton(sp => new Updater(...))). Verify that all of its constructor dependencies (e.g., IPublicAPI and settings for the GitHub repo) are guaranteed to exist.
  • Portable: Explicitly registered via .AddSingleton<Portable>().

Since Ioc.Default.GetRequiredService throws if a service is missing, consider adding exception handling or, at a minimum, bolstering your integration tests to confirm that these services are always properly registered before navigation occurs.

Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml.cs (3)

1-5: Updated imports to support dependency injection pattern!

The added imports support the transition to dependency injection, removing the reliance on navigation parameters for obtaining the Settings instance.


17-17: Good refactoring to dependency injection!

This change improves the code by replacing navigation parameter extraction with dependency injection, which:

  • Eliminates conditional checks and error handling for missing navigation data
  • Reduces coupling between components
  • Makes the code more testable by allowing service mocking
  • Creates a consistent pattern across settings panes

This aligns well with modern software design principles and the PR objectives.


11-11:

✅ Verification successful

Consider using the required property pattern for clarity

For fields that must be initialized before use, consider using C#'s required modifier to make this contract explicit.

-private SettingsPanePluginsViewModel _viewModel = null!;
+private required SettingsPanePluginsViewModel _viewModel;

Note: This suggestion assumes you're using C# 11 or later. If not, your current approach with the null-forgiving operator is appropriate.


🌐 Web query:

What C# version added the required modifier for properties?

💡 Result:

The required modifier for properties and fields was introduced in C# 11, released as part of .NET 7 and Visual Studio 2022 version 17.4[1][2][4][6][10]. This feature enforces that designated members must be initialized during object creation, either via constructors or object initializers, improving type safety by ensuring critical properties are not left uninitialized[1][7][8].

Key details about the required modifier in C# 11:

  • Applies to classes, structs, records, and record structs[1][2]
  • Requires initialization through object initializers or constructors marked with [SetsRequiredMembers][1][6]
  • Works with both fields and properties[1][8]
  • Enhances null safety for non-nullable reference types[1][4]

The feature addresses scenarios where developers previously relied on constructors to enforce initialization, allowing more flexible object creation patterns while maintaining compile-time validation[2][7][8].

Citations:


Action: Update Field Declaration with C# 11 'required' Modifier

After verifying that the required modifier was introduced in C# 11 (as part of .NET 7 and Visual Studio 2022 version 17.4), the suggestion to declare the field as required is valid if your project is targeting C# 11 or later. Doing so improves clarity by enforcing that _viewModel is initialized before use.

  • File: Flow.Launcher/SettingPages/Views/SettingsPanePlugins.xaml.cs

  • Location: Line 11

  • Change Suggestion:

    -private SettingsPanePluginsViewModel _viewModel = null!;
    +private required SettingsPanePluginsViewModel _viewModel;

If your project is using an earlier version of C#, it's acceptable to retain the null-forgiving operator. Otherwise, updating to use the required modifier makes the initialization contract explicit.

@Jack251970 Jack251970 added the enhancement New feature or request label Mar 13, 2025
@Jack251970 Jack251970 merged commit c34fd63 into Flow-Launcher:dev Mar 16, 2025
8 checks passed
@jjw24 jjw24 added this to the 1.20.0 milestone Mar 19, 2025
@Jack251970 Jack251970 linked an issue May 15, 2025 that may be closed by this pull request
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Code Quality enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

BUG: Mouse side buttons navigation in Settings causes an unhandled exception
3 participants