Skip to content
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

Introduce Dependency Injection for Better Development Experience #3175

Open
wants to merge 21 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
20ffff6
Use api to call api functions
Jack251970 Jan 9, 2025
8b91050
Add IApp & AppExtensions for accessing the properties & functions fro…
Jack251970 Jan 9, 2025
88e8437
Use api in app extensions to call api functions
Jack251970 Jan 9, 2025
2716c40
Move MessageBoxEx to main project for better development experience
Jack251970 Jan 9, 2025
32cac76
Improve Settings management
Jack251970 Jan 12, 2025
1b76a2b
Use dependency injection for all services
Jack251970 Jan 12, 2025
a748141
Use IPublicAPI instead
Jack251970 Jan 12, 2025
3cb9d1d
Remove IApp & AppExtensions and use dependency injection instead
Jack251970 Jan 12, 2025
2a423f0
Improve code quality
Jack251970 Jan 13, 2025
ff110b3
Fix test project build issue
Jack251970 Jan 13, 2025
c3f71c2
Revert "Fix test project build issue"
Jack251970 Jan 13, 2025
3bebb69
Fix unitest build issue
Jack251970 Jan 13, 2025
8d83849
Improve dependency injection in updater & settings view model & setti…
Jack251970 Jan 13, 2025
cdc5f0e
Merge branch 'dev' into dev4
Jack251970 Jan 13, 2025
ed39937
Initialize App.API earlier & Improve code quality
Jack251970 Jan 21, 2025
8b290a6
Merge branch 'dev' into dev4
Jack251970 Jan 21, 2025
f9983b5
Move dependency injection codes to constructor
Jack251970 Jan 22, 2025
bb25774
Merge branch 'dev' into dev4
Jack251970 Jan 26, 2025
23a1e5b
Initialize public api instance in constructor so that we can use App.…
Jack251970 Jan 27, 2025
ed16d34
Improve code quality
Jack251970 Jan 27, 2025
6a2389f
Fix test project build issue
Jack251970 Jan 27, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 14 additions & 10 deletions Flow.Launcher.Core/Configuration/Portable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,15 @@
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin.SharedCommands;
using System.Linq;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Plugin;

namespace Flow.Launcher.Core.Configuration
{
public class Portable : IPortable
{
private readonly IPublicAPI API = Ioc.Default.GetRequiredService<IPublicAPI>();

/// <summary>
/// As at Squirrel.Windows version 1.5.2, UpdateManager needs to be disposed after finish
/// </summary>
Expand All @@ -40,7 +44,7 @@ public void DisablePortableMode()
#endif
IndicateDeletion(DataLocation.PortableDataPath);

MessageBoxEx.Show("Flow Launcher needs to restart to finish disabling portable mode, " +
API.ShowMsgBox("Flow Launcher needs to restart to finish disabling portable mode, " +
"after the restart your portable data profile will be deleted and roaming data profile kept");

UpdateManager.RestartApp(Constant.ApplicationFileName);
Expand All @@ -64,7 +68,7 @@ public void EnablePortableMode()
#endif
IndicateDeletion(DataLocation.RoamingDataPath);

MessageBoxEx.Show("Flow Launcher needs to restart to finish enabling portable mode, " +
API.ShowMsgBox("Flow Launcher needs to restart to finish enabling portable mode, " +
"after the restart your roaming data profile will be deleted and portable data profile kept");

UpdateManager.RestartApp(Constant.ApplicationFileName);
Expand Down Expand Up @@ -95,13 +99,13 @@ public void RemoveUninstallerEntry()

public void MoveUserDataFolder(string fromLocation, string toLocation)
{
FilesFolders.CopyAll(fromLocation, toLocation, MessageBoxEx.Show);
FilesFolders.CopyAll(fromLocation, toLocation, (s) => API.ShowMsgBox(s));
VerifyUserDataAfterMove(fromLocation, toLocation);
}

public void VerifyUserDataAfterMove(string fromLocation, string toLocation)
{
FilesFolders.VerifyBothFolderFilesEqual(fromLocation, toLocation, MessageBoxEx.Show);
FilesFolders.VerifyBothFolderFilesEqual(fromLocation, toLocation, (s) => API.ShowMsgBox(s));
}

public void CreateShortcuts()
Expand Down Expand Up @@ -157,13 +161,13 @@ public void PreStartCleanUpAfterPortabilityUpdate()
// delete it and prompt the user to pick the portable data location
if (File.Exists(roamingDataDeleteFilePath))
{
FilesFolders.RemoveFolderIfExists(roamingDataDir, MessageBoxEx.Show);
FilesFolders.RemoveFolderIfExists(roamingDataDir, (s) => API.ShowMsgBox(s));

if (MessageBoxEx.Show("Flow Launcher has detected you enabled portable mode, " +
if (API.ShowMsgBox("Flow Launcher has detected you enabled portable mode, " +
"would you like to move it to a different location?", string.Empty,
MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
FilesFolders.OpenPath(Constant.RootDirectory, MessageBoxEx.Show);
FilesFolders.OpenPath(Constant.RootDirectory, (s) => API.ShowMsgBox(s));

Environment.Exit(0);
}
Expand All @@ -172,9 +176,9 @@ public void PreStartCleanUpAfterPortabilityUpdate()
// delete it and notify the user about it.
else if (File.Exists(portableDataDeleteFilePath))
{
FilesFolders.RemoveFolderIfExists(portableDataDir, MessageBoxEx.Show);
FilesFolders.RemoveFolderIfExists(portableDataDir, (s) => API.ShowMsgBox(s));

MessageBoxEx.Show("Flow Launcher has detected you disabled portable mode, " +
API.ShowMsgBox("Flow Launcher has detected you disabled portable mode, " +
"the relevant shortcuts and uninstaller entry have been created");
}
}
Expand All @@ -186,7 +190,7 @@ public bool CanUpdatePortability()

if (roamingLocationExists && portableLocationExists)
{
MessageBoxEx.Show(string.Format("Flow Launcher detected your user data exists both in {0} and " +
API.ShowMsgBox(string.Format("Flow Launcher detected your user data exists both in {0} and " +
"{1}. {2}{2}Please delete {1} in order to proceed. No changes have occurred.",
DataLocation.PortableDataPath, DataLocation.RoamingDataPath, Environment.NewLine));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@
using System.Windows;
using System.Windows.Forms;
using Flow.Launcher.Core.Resource;
using CommunityToolkit.Mvvm.DependencyInjection;

namespace Flow.Launcher.Core.ExternalPlugins.Environments
{
public abstract class AbstractPluginEnvironment
{
protected readonly IPublicAPI API = Ioc.Default.GetRequiredService<IPublicAPI>();
Jack251970 marked this conversation as resolved.
Show resolved Hide resolved

internal abstract string Language { get; }

internal abstract string EnvName { get; }
Expand All @@ -25,7 +28,7 @@ public abstract class AbstractPluginEnvironment

internal virtual string FileDialogFilter => string.Empty;

internal abstract string PluginsSettingsFilePath { get; set; }
internal abstract string PluginsSettingsFilePath { get; set; }

internal List<PluginMetadata> PluginMetadataList;

Expand Down Expand Up @@ -57,7 +60,7 @@ internal IEnumerable<PluginPair> Setup()
EnvName,
Environment.NewLine
);
if (MessageBoxEx.Show(noRuntimeMessage, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
if (API.ShowMsgBox(noRuntimeMessage, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
{
var msg = string.Format(InternationalizationManager.Instance.GetTranslation("runtimePluginChooseRuntimeExecutable"), EnvName);
string selectedFile;
Expand All @@ -82,7 +85,7 @@ internal IEnumerable<PluginPair> Setup()
}
else
{
MessageBoxEx.Show(string.Format(InternationalizationManager.Instance.GetTranslation("runtimePluginUnableToSetExecutablePath"), Language));
API.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("runtimePluginUnableToSetExecutablePath"), Language));
Log.Error("PluginsLoader",
$"Not able to successfully set {EnvName} path, setting's plugin executable path variable is still an empty string.",
$"{Language}Environment");
Expand All @@ -98,7 +101,7 @@ private void EnsureLatestInstalled(string expectedPath, string currentPath, stri
if (expectedPath == currentPath)
return;

FilesFolders.RemoveFolderIfExists(installedDirPath, MessageBoxEx.Show);
FilesFolders.RemoveFolderIfExists(installedDirPath, (s) => API.ShowMsgBox(s));

InstallEnvironment();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ internal PythonEnvironment(List<PluginMetadata> pluginMetadataList, PluginsSetti

internal override void InstallEnvironment()
{
FilesFolders.RemoveFolderIfExists(InstallPath, MessageBoxEx.Show);
FilesFolders.RemoveFolderIfExists(InstallPath, (s) => API.ShowMsgBox(s));

// Python 3.11.4 is no longer Windows 7 compatible. If user is on Win 7 and
// uses Python plugin they need to custom install and use v3.8.9
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ internal TypeScriptEnvironment(List<PluginMetadata> pluginMetadataList, PluginsS

internal override void InstallEnvironment()
{
FilesFolders.RemoveFolderIfExists(InstallPath, MessageBoxEx.Show);
FilesFolders.RemoveFolderIfExists(InstallPath, (s) => API.ShowMsgBox(s));

DroplexPackage.Drop(App.nodejs_16_18_0, InstallPath).Wait();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ internal TypeScriptV2Environment(List<PluginMetadata> pluginMetadataList, Plugin

internal override void InstallEnvironment()
{
FilesFolders.RemoveFolderIfExists(InstallPath, MessageBoxEx.Show);
FilesFolders.RemoveFolderIfExists(InstallPath, (s) => API.ShowMsgBox(s));

DroplexPackage.Drop(App.nodejs_16_18_0, InstallPath).Wait();

Expand Down
2 changes: 1 addition & 1 deletion Flow.Launcher.Core/Plugin/PluginManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@ internal static void InstallPlugin(UserPlugin plugin, string zipFilePath, bool c

var newPluginPath = Path.Combine(installDirectory, folderName);

FilesFolders.CopyAll(pluginFolderPath, newPluginPath, MessageBoxEx.Show);
FilesFolders.CopyAll(pluginFolderPath, newPluginPath, (s) => API.ShowMsgBox(s));

Directory.Delete(tempFolderPluginPath, true);

Expand Down
3 changes: 2 additions & 1 deletion Flow.Launcher.Core/Plugin/PluginsLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Reflection;
using System.Threading.Tasks;
using System.Windows;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Core.ExternalPlugins.Environments;
#pragma warning disable IDE0005
using Flow.Launcher.Infrastructure.Logger;
Expand Down Expand Up @@ -119,7 +120,7 @@ public static IEnumerable<PluginPair> DotNetPlugins(List<PluginMetadata> source)

_ = Task.Run(() =>
{
MessageBoxEx.Show($"{errorMessage}{Environment.NewLine}{Environment.NewLine}" +
Ioc.Default.GetRequiredService<IPublicAPI>().ShowMsgBox($"{errorMessage}{Environment.NewLine}{Environment.NewLine}" +
$"{errorPluginString}{Environment.NewLine}{Environment.NewLine}" +
$"Please refer to the logs for more information", "",
MessageBoxButton.OK, MessageBoxImage.Warning);
Expand Down
3 changes: 2 additions & 1 deletion Flow.Launcher.Core/Resource/Internationalization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using Flow.Launcher.Plugin;
using System.Globalization;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.DependencyInjection;

namespace Flow.Launcher.Core.Resource
{
Expand Down Expand Up @@ -124,7 +125,7 @@ public bool PromptShouldUsePinyin(string languageCodeToSet)
// "Do you want to search with pinyin?"
string text = languageToSet == AvailableLanguages.Chinese ? "是否启用拼音搜索?" : "是否啓用拼音搜索?" ;

if (MessageBoxEx.Show(text, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
if (Ioc.Default.GetRequiredService<IPublicAPI>().ShowMsgBox(text, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.No)
return false;

return true;
Expand Down
7 changes: 5 additions & 2 deletions Flow.Launcher.Core/Resource/Theme.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Plugin;

namespace Flow.Launcher.Core.Resource
{
Expand All @@ -22,6 +24,7 @@ public class Theme

private const int ShadowExtraMargin = 32;

private readonly IPublicAPI API = Ioc.Default.GetRequiredService<IPublicAPI>();
private readonly List<string> _themeDirectories = new List<string>();
private ResourceDictionary _oldResource;
private string _oldTheme;
Expand Down Expand Up @@ -108,7 +111,7 @@ public bool ChangeTheme(string theme)
Log.Error($"|Theme.ChangeTheme|Theme <{theme}> path can't be found");
if (theme != defaultTheme)
{
MessageBoxEx.Show(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_path_not_exists"), theme));
API.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_path_not_exists"), theme));
ChangeTheme(defaultTheme);
}
return false;
Expand All @@ -118,7 +121,7 @@ public bool ChangeTheme(string theme)
Log.Error($"|Theme.ChangeTheme|Theme <{theme}> fail to parse");
if (theme != defaultTheme)
{
MessageBoxEx.Show(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_parse_error"), theme));
API.ShowMsgBox(string.Format(InternationalizationManager.Instance.GetTranslation("theme_load_failure_parse_error"), theme));
ChangeTheme(defaultTheme);
}
return false;
Expand Down
31 changes: 17 additions & 14 deletions Flow.Launcher.Core/Updater.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,28 +17,31 @@
using Flow.Launcher.Plugin;
using System.Text.Json.Serialization;
using System.Threading;
using CommunityToolkit.Mvvm.DependencyInjection;

namespace Flow.Launcher.Core
{
public class Updater
{
public string GitHubRepository { get; }
private readonly IPublicAPI API = Ioc.Default.GetRequiredService<IPublicAPI>();

public Updater(string gitHubRepository)
public string GitHubRepository { get; set; }

public void Initialize(string gitHubRepository)
{
GitHubRepository = gitHubRepository;
}
Jack251970 marked this conversation as resolved.
Show resolved Hide resolved

private SemaphoreSlim UpdateLock { get; } = new SemaphoreSlim(1);

public async Task UpdateAppAsync(IPublicAPI api, bool silentUpdate = true)
public async Task UpdateAppAsync(bool silentUpdate = true)
{
await UpdateLock.WaitAsync().ConfigureAwait(false);
try
{
if (!silentUpdate)
api.ShowMsg(api.GetTranslation("pleaseWait"),
api.GetTranslation("update_flowlauncher_update_check"));
API.ShowMsg(API.GetTranslation("pleaseWait"),
API.GetTranslation("update_flowlauncher_update_check"));

using var updateManager = await GitHubUpdateManagerAsync(GitHubRepository).ConfigureAwait(false);

Expand All @@ -53,13 +56,13 @@ public async Task UpdateAppAsync(IPublicAPI api, bool silentUpdate = true)
if (newReleaseVersion <= currentVersion)
{
if (!silentUpdate)
MessageBoxEx.Show(api.GetTranslation("update_flowlauncher_already_on_latest"));
API.ShowMsgBox(API.GetTranslation("update_flowlauncher_already_on_latest"));
return;
}

if (!silentUpdate)
api.ShowMsg(api.GetTranslation("update_flowlauncher_update_found"),
api.GetTranslation("update_flowlauncher_updating"));
API.ShowMsg(API.GetTranslation("update_flowlauncher_update_found"),
API.GetTranslation("update_flowlauncher_updating"));

await updateManager.DownloadReleases(newUpdateInfo.ReleasesToApply).ConfigureAwait(false);

Expand All @@ -68,9 +71,9 @@ public async Task UpdateAppAsync(IPublicAPI api, bool silentUpdate = true)
if (DataLocation.PortableDataLocationInUse())
{
var targetDestination = updateManager.RootAppDirectory + $"\\app-{newReleaseVersion.ToString()}\\{DataLocation.PortableFolderName}";
FilesFolders.CopyAll(DataLocation.PortableDataPath, targetDestination, MessageBoxEx.Show);
if (!FilesFolders.VerifyBothFolderFilesEqual(DataLocation.PortableDataPath, targetDestination, MessageBoxEx.Show))
MessageBoxEx.Show(string.Format(api.GetTranslation("update_flowlauncher_fail_moving_portable_user_profile_data"),
FilesFolders.CopyAll(DataLocation.PortableDataPath, targetDestination, (s) => API.ShowMsgBox(s));
if (!FilesFolders.VerifyBothFolderFilesEqual(DataLocation.PortableDataPath, targetDestination, (s) => API.ShowMsgBox(s)))
API.ShowMsgBox(string.Format(API.GetTranslation("update_flowlauncher_fail_moving_portable_user_profile_data"),
DataLocation.PortableDataPath,
targetDestination));
}
Expand All @@ -83,7 +86,7 @@ public async Task UpdateAppAsync(IPublicAPI api, bool silentUpdate = true)

Log.Info($"|Updater.UpdateApp|Update success:{newVersionTips}");

if (MessageBoxEx.Show(newVersionTips, api.GetTranslation("update_flowlauncher_new_update"), MessageBoxButton.YesNo) == MessageBoxResult.Yes)
if (API.ShowMsgBox(newVersionTips, API.GetTranslation("update_flowlauncher_new_update"), MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
UpdateManager.RestartApp(Constant.ApplicationFileName);
}
Expand All @@ -96,8 +99,8 @@ public async Task UpdateAppAsync(IPublicAPI api, bool silentUpdate = true)
Log.Exception($"|Updater.UpdateApp|Error Occurred", e);

if (!silentUpdate)
api.ShowMsg(api.GetTranslation("update_flowlauncher_fail"),
api.GetTranslation("update_flowlauncher_check_connection"));
API.ShowMsg(API.GetTranslation("update_flowlauncher_fail"),
API.GetTranslation("update_flowlauncher_check_connection"));
}
finally
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
<ItemGroup>
<PackageReference Include="Ben.Demystifier" Version="0.4.1" />
<PackageReference Include="BitFaster.Caching" Version="2.5.2" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
<PackageReference Include="Fody" Version="6.5.5">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
8 changes: 7 additions & 1 deletion Flow.Launcher.Infrastructure/PinyinAlphabet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using JetBrains.Annotations;
using Flow.Launcher.Infrastructure.UserSettings;
using ToolGood.Words.Pinyin;
using CommunityToolkit.Mvvm.DependencyInjection;

namespace Flow.Launcher.Infrastructure
{
Expand Down Expand Up @@ -129,7 +130,12 @@ public class PinyinAlphabet : IAlphabet

private Settings _settings;

public void Initialize([NotNull] Settings settings)
public PinyinAlphabet()
{
Initialize(Ioc.Default.GetRequiredService<Settings>());
}
Jack251970 marked this conversation as resolved.
Show resolved Hide resolved

private void Initialize([NotNull] Settings settings)
{
_settings = settings ?? throw new ArgumentNullException(nameof(settings));
}
Expand Down
Loading
Loading