diff --git a/SolutionParityChecker.App/SolutionParityChecker.App.csproj b/SolutionParityChecker.App/SolutionParityChecker.App.csproj
index 081513a..54cc2ec 100644
--- a/SolutionParityChecker.App/SolutionParityChecker.App.csproj
+++ b/SolutionParityChecker.App/SolutionParityChecker.App.csproj
@@ -26,4 +26,8 @@
+
+
+
+
diff --git a/SolutionParityChecker.App/ViewModels/MainWindowViewModel.cs b/SolutionParityChecker.App/ViewModels/MainWindowViewModel.cs
index dac9045..c56147a 100644
--- a/SolutionParityChecker.App/ViewModels/MainWindowViewModel.cs
+++ b/SolutionParityChecker.App/ViewModels/MainWindowViewModel.cs
@@ -1,4 +1,6 @@
using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
using System.IO;
using System.Text;
using System.Threading;
@@ -13,14 +15,37 @@ namespace SolutionParityChecker.App.ViewModels;
public partial class MainWindowViewModel : ViewModelBase
{
- public string SolutionFolderPath { get; set; } = string.Empty;
- public string SolutionFilePath { get; set; } = string.Empty;
+ [ObservableProperty]
+ private string _solutionFolderPath;
+
+ [ObservableProperty]
+ private string _solutionFilePath;
[ObservableProperty]
private string? _fileText;
+ [ObservableProperty]
+ private ObservableCollection _parityResults = new ObservableCollection()
+ {
+ "Test"
+ };
+
[RelayCommand]
- private async Task OpenFile(CancellationToken token)
+ private async Task ExecuteParityChecker(CancellationToken token)
+ {
+ var results = SolutionParityChecker.CompareSolutionAndCSharpProjects(
+ SolutionFolderPath,
+ SolutionFilePath
+ );
+ ParityResults.Clear();
+ foreach (var result in results)
+ {
+ ParityResults.Add(result);
+ }
+ }
+
+ [RelayCommand]
+ private async Task LoadSolutionFile(CancellationToken token)
{
ErrorMessages?.Clear();
try
@@ -29,17 +54,7 @@ public partial class MainWindowViewModel : ViewModelBase
if (file is null)
return;
- // Limit the text file to 1MB so that the demo won't lag.
- if ((await file.GetBasicPropertiesAsync()).Size <= 1024 * 1024 * 1)
- {
- await using var readStream = await file.OpenReadAsync();
- using var reader = new StreamReader(readStream);
- FileText = await reader.ReadToEndAsync(token);
- }
- else
- {
- throw new Exception("File exceeded 1MB limit.");
- }
+ SolutionFilePath = file.Path.AbsolutePath;
}
catch (Exception e)
{
@@ -48,26 +63,16 @@ public partial class MainWindowViewModel : ViewModelBase
}
[RelayCommand]
- private async Task SaveFile()
+ private async Task LoadSolutionFolder(CancellationToken token)
{
ErrorMessages?.Clear();
try
{
- var file = await DoSaveFilePickerAsync();
- if (file is null)
+ var folder = await DoOpenFolderPickerAsync();
+ if (folder is null)
return;
- // Limit the text file to 1MB so that the demo won't lag.
- if (FileText?.Length <= 1024 * 1024 * 1)
- {
- var stream = new MemoryStream(Encoding.Default.GetBytes((string)FileText));
- await using var writeStream = await file.OpenWriteAsync();
- await stream.CopyToAsync(writeStream);
- }
- else
- {
- throw new Exception("File exceeded 1MB limit.");
- }
+ SolutionFolderPath = folder.Path.AbsolutePath;
}
catch (Exception e)
{
@@ -98,7 +103,7 @@ public partial class MainWindowViewModel : ViewModelBase
return files?.Count >= 1 ? files[0] : null;
}
- private async Task DoSaveFilePickerAsync()
+ private async Task DoOpenFolderPickerAsync()
{
// For learning purposes, we opted to directly get the reference
// for StorageProvider APIs here inside the ViewModel.
@@ -106,7 +111,7 @@ public partial class MainWindowViewModel : ViewModelBase
// For your real-world apps, you should follow the MVVM principles
// by making service classes and locating them with DI/IoC.
- // See DepInject project for a sample of how to accomplish this.
+ // See IoCFileOps project for an example of how to accomplish this.
if (
Application.Current?.ApplicationLifetime
is not IClassicDesktopStyleApplicationLifetime desktop
@@ -114,8 +119,10 @@ public partial class MainWindowViewModel : ViewModelBase
)
throw new NullReferenceException("Missing StorageProvider instance.");
- return await provider.SaveFilePickerAsync(
- new FilePickerSaveOptions() { Title = "Save Text File" }
+ var folder = await provider.OpenFolderPickerAsync(
+ new FolderPickerOpenOptions() { Title = "Open Text File", AllowMultiple = false }
);
+
+ return folder?.Count >= 1 ? folder[0] : null;
}
}
diff --git a/SolutionParityChecker.App/ViewModels/ViewModelBase.cs b/SolutionParityChecker.App/ViewModels/ViewModelBase.cs
index ebf744e..f85eddd 100644
--- a/SolutionParityChecker.App/ViewModels/ViewModelBase.cs
+++ b/SolutionParityChecker.App/ViewModels/ViewModelBase.cs
@@ -9,7 +9,7 @@ public partial class ViewModelBase : ObservableObject
{
ErrorMessages = new ObservableCollection();
}
-
- [ObservableProperty]
+
+ [ObservableProperty]
private ObservableCollection? _errorMessages;
-}
\ No newline at end of file
+}
diff --git a/SolutionParityChecker.App/Views/MainWindow.axaml b/SolutionParityChecker.App/Views/MainWindow.axaml
index 639da74..aac9435 100644
--- a/SolutionParityChecker.App/Views/MainWindow.axaml
+++ b/SolutionParityChecker.App/Views/MainWindow.axaml
@@ -11,18 +11,18 @@
-
+
Welcome to Avalonia!
-
-
-
-
+
+
+
-
+
+
diff --git a/SolutionParityChecker.App/Views/MainWindow.axaml.cs b/SolutionParityChecker.App/Views/MainWindow.axaml.cs
index 53ebbc5..ca21c9d 100644
--- a/SolutionParityChecker.App/Views/MainWindow.axaml.cs
+++ b/SolutionParityChecker.App/Views/MainWindow.axaml.cs
@@ -1,5 +1,6 @@
using Avalonia.Controls;
using Avalonia.Interactivity;
+using SolutionParityChecker.App.ViewModels;
namespace SolutionParityChecker.App.Views;
@@ -9,14 +10,4 @@ public partial class MainWindow : Window
{
InitializeComponent();
}
-
- private void LoadSolutionFolder(object? sender, RoutedEventArgs e)
- {
- SolutionFolderPath.Text = "Solution folder path";
- }
-
- private void LoadSolutionFile(object? sender, RoutedEventArgs e)
- {
- SolutionFilePath.Text = "Solution file path";
- }
}
diff --git a/SolutionParityChecker/SolutionParityChecker.cs b/SolutionParityChecker/SolutionParityChecker.cs
index 2812b75..5f5e338 100644
--- a/SolutionParityChecker/SolutionParityChecker.cs
+++ b/SolutionParityChecker/SolutionParityChecker.cs
@@ -4,13 +4,26 @@ namespace SolutionParityChecker;
public static class SolutionParityChecker
{
- public static void CompareSolutionAndCSharpProjects(
+ public static List CompareSolutionAndCSharpProjects(
string solutionFolderPath,
string solutionFilePath
- ) { }
+ )
+ {
+ var csprojList = RetrieveAllCSharpProjectNamesFromFolder(solutionFolderPath);
+ var solutionFile = ParseSolutionFileFromPath(solutionFilePath);
+ ArgumentNullException.ThrowIfNull(solutionFile);
+ var projectsMissingFromSolution = FindProjectsMissingFromSolution(csprojList, solutionFile);
+
+ return projectsMissingFromSolution;
+ }
public static string[] RetrieveAllCSharpProjectNamesFromFolder(string solutionFolderPath)
{
+ // if solutionFolderPath does not end with a slash, add one
+ if (solutionFolderPath[^1] != Path.DirectorySeparatorChar)
+ {
+ solutionFolderPath += Path.DirectorySeparatorChar;
+ }
var csprojList = Directory.GetFiles(
solutionFolderPath,
"*.csproj",