From 09d8bc7ba8a0f70ff5a83a58868854ddd27f9ac5 Mon Sep 17 00:00:00 2001 From: Cal <42492716+ly3027929699@users.noreply.github.com> Date: Tue, 5 Dec 2023 20:11:38 +0800 Subject: [PATCH] =?UTF-8?q?DI=20=E6=B3=A8=E5=85=A5=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F=EF=BC=8Cweb=E5=B9=B3=E5=8F=B0=E4=B8=8D?= =?UTF-8?q?=E6=94=AF=E6=8C=81System.IO.File?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Notes.Android/FileService.cs | 53 +++++++++++++++++++++ Notes.Android/MainActivity.cs | 5 ++ Notes.Browser/Notes.Browser.csproj | 3 ++ Notes.Desktop/FileService.cs | 53 +++++++++++++++++++++ Notes.Desktop/Program.cs | 11 ++++- Notes/App.axaml.cs | 3 ++ Notes/IFileService.cs | 67 +++++++++++++++++++++++++++ Notes/Models/Note.cs | 25 +++++----- Notes/ViewModels/AboutViewModel.cs | 2 +- Notes/ViewModels/AllNotesViewModel.cs | 4 +- Notes/ViewModels/IServices.cs | 8 ++++ Notes/ViewModels/MainViewModel.cs | 32 +------------ Notes/ViewModels/NoteViewModel.cs | 4 +- Notes/ViewModels/Services.cs | 27 +++++++++++ Notes/Views/MainView.axaml.cs | 1 - 15 files changed, 246 insertions(+), 52 deletions(-) create mode 100644 Notes.Android/FileService.cs create mode 100644 Notes.Desktop/FileService.cs create mode 100644 Notes/IFileService.cs create mode 100644 Notes/ViewModels/IServices.cs create mode 100644 Notes/ViewModels/Services.cs diff --git a/Notes.Android/FileService.cs b/Notes.Android/FileService.cs new file mode 100644 index 0000000..a1d110d --- /dev/null +++ b/Notes.Android/FileService.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.IO; + +namespace Notes.Android; + +class FileService : IFileService +{ + public string Combine(string args0, string args1) + { + return Path.Combine(args0, args1); + } + + public string GetRandomFileName() + { + return Path.GetRandomFileName(); + } + + public IEnumerable EnumerateFiles(string path, string patten) + { + return Directory.EnumerateFiles(path, patten); + } + + public string GetFileName(string filename) + { + return Path.GetFileName(filename); + } + + public string ReadAllText(string filename) + { + return File.ReadAllText(filename); + } + + public DateTime GetLastWriteTime(string filename) + { + return File.GetLastWriteTime(filename); + } + + public bool ExistsFile(string filename) + { + return File.Exists(filename); + } + + public void Delete(string path) + { + File.Delete(path); + } + + public void WriteAllText(string path, string text) + { + File.WriteAllText(path, text); + } +} \ No newline at end of file diff --git a/Notes.Android/MainActivity.cs b/Notes.Android/MainActivity.cs index 4476ae6..5da2a85 100644 --- a/Notes.Android/MainActivity.cs +++ b/Notes.Android/MainActivity.cs @@ -3,6 +3,7 @@ using Android.Content.PM; using Avalonia; using Avalonia.Android; using Avalonia.ReactiveUI; +using Notes.ViewModels; namespace Notes.Android; @@ -16,6 +17,10 @@ public class MainActivity : AvaloniaMainActivity { protected override AppBuilder CustomizeAppBuilder(AppBuilder builder) { + + var services = new Services(); + services.Register(new FileService()); + App.services = services; return base.CustomizeAppBuilder(builder) .WithInterFont() .UseReactiveUI(); diff --git a/Notes.Browser/Notes.Browser.csproj b/Notes.Browser/Notes.Browser.csproj index bb0cfec..5822461 100644 --- a/Notes.Browser/Notes.Browser.csproj +++ b/Notes.Browser/Notes.Browser.csproj @@ -4,6 +4,9 @@ browser-wasm AppBundle\main.js Exe + true + 1 + true diff --git a/Notes.Desktop/FileService.cs b/Notes.Desktop/FileService.cs new file mode 100644 index 0000000..feeb34d --- /dev/null +++ b/Notes.Desktop/FileService.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.IO; + +namespace Notes.Desktop; + +class FileService: IFileService +{ + public string Combine(string args0, string args1) + { + return Path.Combine(args0, args1); + } + + public string GetRandomFileName() + { + return Path.GetRandomFileName(); + } + + public IEnumerable EnumerateFiles(string path, string patten) + { + return Directory.EnumerateFiles(path,patten); + } + + public string GetFileName(string filename) + { + return Path.GetFileName(filename); + } + + public string ReadAllText(string filename) + { + return File.ReadAllText(filename); + } + + public DateTime GetLastWriteTime(string filename) + { + return File.GetLastWriteTime(filename); + } + + public bool ExistsFile(string filename) + { + return File.Exists(filename); + } + + public void Delete(string path) + { + File.Delete(path); + } + + public void WriteAllText(string path, string text) + { + File.WriteAllText(path,text); + } +} \ No newline at end of file diff --git a/Notes.Desktop/Program.cs b/Notes.Desktop/Program.cs index 80a11ba..340ac7c 100644 --- a/Notes.Desktop/Program.cs +++ b/Notes.Desktop/Program.cs @@ -1,6 +1,7 @@ using System; using Avalonia; using Avalonia.ReactiveUI; +using Notes.ViewModels; namespace Notes.Desktop; @@ -10,8 +11,14 @@ sealed class Program // SynchronizationContext-reliant code before AppMain is called: things aren't initialized // yet and stuff might break. [STAThread] - public static void Main(string[] args) => BuildAvaloniaApp() - .StartWithClassicDesktopLifetime(args); + public static void Main(string[] args) + { + var services = new Services(); + services.Register(new FileService()); + App.services = services; + BuildAvaloniaApp() + .StartWithClassicDesktopLifetime(args); + } // Avalonia configuration, don't remove; also used by visual designer. public static AppBuilder BuildAvaloniaApp() diff --git a/Notes/App.axaml.cs b/Notes/App.axaml.cs index 247e5a1..1edc419 100644 --- a/Notes/App.axaml.cs +++ b/Notes/App.axaml.cs @@ -8,9 +8,12 @@ namespace Notes; public partial class App : Application { + public static IServices services { get; set; } + public override void Initialize() { AvaloniaXamlLoader.Load(this); + FileSystem.fileService = services.GetSafeAs(); } public override void OnFrameworkInitializationCompleted() diff --git a/Notes/IFileService.cs b/Notes/IFileService.cs new file mode 100644 index 0000000..b3a8e5d --- /dev/null +++ b/Notes/IFileService.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; + +namespace Notes; + +public interface IFileService +{ + string Combine(string args0, string args1); + string GetRandomFileName(); + IEnumerable EnumerateFiles(string path, string patten); + string GetFileName(string filename); + string ReadAllText(string filename); + DateTime GetLastWriteTime(string filename); + bool ExistsFile(string filename); + void Delete(string path); + void WriteAllText(string path, string text); +} + +public static class FileSystem +{ + public static IFileService fileService; + + public static string Combine(string args0, string args1) + { + return fileService.Combine(args0, args1); + } + + public static string GetRandomFileName() + { + return fileService.GetRandomFileName(); + } + + public static IEnumerable EnumerateFiles(string path, string patten) + { + return fileService.EnumerateFiles(path, patten); + } + + public static string GetFileName(string filename) + { + return fileService.GetFileName(filename); + } + + public static string ReadAllText(string filename) + { + return fileService.ReadAllText(filename); + } + + public static DateTime GetLastWriteTime(string filename) + { + return fileService.GetLastWriteTime(filename); + } + + public static bool ExistsFile(string filename) + { + return fileService.ExistsFile(filename); + } + + public static void Delete(string filename) + { + fileService.Delete(filename); + } + + public static void WriteAllText(string path, string text) + { + fileService.WriteAllText(path, text); + } +} \ No newline at end of file diff --git a/Notes/Models/Note.cs b/Notes/Models/Note.cs index 0136a52..8945815 100644 --- a/Notes/Models/Note.cs +++ b/Notes/Models/Note.cs @@ -1,7 +1,6 @@  using System; using System.Collections.Generic; -using System.IO; using System.Linq; using Utils; @@ -20,37 +19,37 @@ public class Note { get { - var appDataDirectory = Path.Combine(AppContext.BaseDirectory, "Data"); + var appDataDirectory = FileSystem.Combine(AppContext.BaseDirectory, "Data"); IOUtils.EnsureDirectory(appDataDirectory,false); return appDataDirectory; } } public Note() { - Filename = $"{Path.GetRandomFileName()}{Extension}"; + Filename = $"{FileSystem.GetRandomFileName()}{Extension}"; Date = DateTime.Now; Text = ""; } public void Save() => - File.WriteAllText(Path.Combine(AppDataDirectory, Filename), Text); + FileSystem.WriteAllText(FileSystem.Combine(AppDataDirectory, Filename), Text); public void Delete() => - File.Delete(Path.Combine(AppDataDirectory, Filename)); + FileSystem.Delete(FileSystem.Combine(AppDataDirectory, Filename)); public static Note Load(string filename) { - filename = Path.Combine(AppDataDirectory, filename); + filename = FileSystem.Combine(AppDataDirectory, filename); - if (!File.Exists(filename)) - throw new FileNotFoundException("Unable to find file on local storage.", filename); + if (!FileSystem.ExistsFile(filename)) + throw new InvalidOperationException($"Unable to find file '{filename}' on local storage."); return new() { - Filename = Path.GetFileName(filename), - Text = File.ReadAllText(filename), - Date = File.GetLastWriteTime(filename) + Filename = FileSystem.GetFileName(filename), + Text = FileSystem.ReadAllText(filename), + Date = FileSystem.GetLastWriteTime(filename) }; } @@ -60,13 +59,13 @@ public class Note string appDataPath = AppDataDirectory; // Use Linq extensions to load the *.notes.txt files. - return Directory + return FileSystem // Select the file names from the directory .EnumerateFiles(appDataPath, "*.notes.txt") // Each file name is used to load a note - .Select(filename => Load(Path.GetFileName(filename))) + .Select(filename => Load(FileSystem.GetFileName(filename))) // With the final collection of notes, order them by date .OrderByDescending(note => note.Date); diff --git a/Notes/ViewModels/AboutViewModel.cs b/Notes/ViewModels/AboutViewModel.cs index ea5b152..c6a800e 100644 --- a/Notes/ViewModels/AboutViewModel.cs +++ b/Notes/ViewModels/AboutViewModel.cs @@ -14,7 +14,7 @@ public partial class AboutViewModel:ViewModelBase [RelayCommand] public void ShowAllNotes() { - _services.GetAs().Navitation(this._services); + _services.GetSafeAs().Navitation(this._services); } [Obsolete("Used by designer",true)] diff --git a/Notes/ViewModels/AllNotesViewModel.cs b/Notes/ViewModels/AllNotesViewModel.cs index 140ba8a..7dd5e49 100644 --- a/Notes/ViewModels/AllNotesViewModel.cs +++ b/Notes/ViewModels/AllNotesViewModel.cs @@ -26,7 +26,7 @@ public partial class AllNotesViewModel: ViewModelBase { var note = new Note(); note.Filename = string.Empty; - this._services.GetAs().Navitation(this._services,this,note); + this._services.GetSafeAs().Navitation(this._services,this,note); } [RelayCommand] public void DeleteNote(ISelectionModel selectionModel) @@ -43,7 +43,7 @@ public partial class AllNotesViewModel: ViewModelBase [RelayCommand] public void OpenAbout() { - this._services.GetAs().Navitation(this._services); + this._services.GetSafeAs().Navitation(this._services); } [Obsolete("Used by designer",true)] diff --git a/Notes/ViewModels/IServices.cs b/Notes/ViewModels/IServices.cs new file mode 100644 index 0000000..db76055 --- /dev/null +++ b/Notes/ViewModels/IServices.cs @@ -0,0 +1,8 @@ +namespace Notes.ViewModels; + +public interface IServices +{ + void Register(T t); + T? Get(); + T GetSafeAs(); +} \ No newline at end of file diff --git a/Notes/ViewModels/MainViewModel.cs b/Notes/ViewModels/MainViewModel.cs index ddfa105..776ec1d 100644 --- a/Notes/ViewModels/MainViewModel.cs +++ b/Notes/ViewModels/MainViewModel.cs @@ -1,40 +1,10 @@ using System; -using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using CommunityToolkit.Mvvm.ComponentModel; using Utils; namespace Notes.ViewModels; -public interface IServices -{ - void Register(T t); - T? Get(); - T GetAs(); -} - -public sealed class Sevices:IServices -{ - private readonly Dictionary map = new Dictionary(); - public void Register(T t) - { - map.Add(typeof(T), t); - } - - public T? Get() - { - map.TryGetValue(typeof(T), out var t); - return (T?)t; - } - - public T GetAs() - { - T? foo = this.Get(); - if (foo is { } t) - return t; - throw new InvalidOperationException($"Not find type '{typeof(T)}'"); - } -} public partial class MainViewModel:ViewModelBase { /// @@ -47,7 +17,7 @@ public partial class MainViewModel:ViewModelBase public MainViewModel() { - _service = new Sevices(); + _service = App.services; _service.Register(this); _contentViewModel = new AboutViewModel(_service); } diff --git a/Notes/ViewModels/NoteViewModel.cs b/Notes/ViewModels/NoteViewModel.cs index 2d10e68..e6bf341 100644 --- a/Notes/ViewModels/NoteViewModel.cs +++ b/Notes/ViewModels/NoteViewModel.cs @@ -51,13 +51,13 @@ public partial class NoteViewModel : ViewModelBase public void Back() { - _services.GetAs().Navitation(this._services); + _services.GetSafeAs().Navitation(this._services); } [RelayCommand] public void OpenNote() { - this._services.GetAs().Navitation(this._services, this.AllNotesViewModel, this.Note); + this._services.GetSafeAs().Navitation(this._services, this.AllNotesViewModel, this.Note); } diff --git a/Notes/ViewModels/Services.cs b/Notes/ViewModels/Services.cs new file mode 100644 index 0000000..1f99fb9 --- /dev/null +++ b/Notes/ViewModels/Services.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; + +namespace Notes.ViewModels; + +public sealed class Services:IServices +{ + private readonly Dictionary map = new Dictionary(); + public void Register(T t) + { + this.map.Add(typeof(T), t); + } + + public T? Get() + { + this.map.TryGetValue(typeof(T), out var t); + return (T?)t; + } + + public T GetSafeAs() + { + T? foo = this.Get(); + if (foo is { } t) + return t; + throw new InvalidOperationException($"Not find type '{typeof(T)}'"); + } +} \ No newline at end of file diff --git a/Notes/Views/MainView.axaml.cs b/Notes/Views/MainView.axaml.cs index d95730c..5739052 100644 --- a/Notes/Views/MainView.axaml.cs +++ b/Notes/Views/MainView.axaml.cs @@ -9,7 +9,6 @@ public partial class MainView : UserControl { public MainView() { - DataContext = new MainViewModel(); InitializeComponent(); } } \ No newline at end of file