diff --git a/DotNetSolutionTools.App/DotNetSolutionTools.App.csproj b/DotNetSolutionTools.App/DotNetSolutionTools.App.csproj
index 42d8291..39a8aeb 100644
--- a/DotNetSolutionTools.App/DotNetSolutionTools.App.csproj
+++ b/DotNetSolutionTools.App/DotNetSolutionTools.App.csproj
@@ -6,6 +6,7 @@
true
app.manifest
true
+ enable
@@ -28,6 +29,6 @@
-
+
diff --git a/DotNetSolutionTools.App/Services/FileService.cs b/DotNetSolutionTools.App/Services/FileService.cs
new file mode 100644
index 0000000..72441f0
--- /dev/null
+++ b/DotNetSolutionTools.App/Services/FileService.cs
@@ -0,0 +1,40 @@
+using Avalonia;
+using Avalonia.Controls.ApplicationLifetimes;
+using Avalonia.Platform.Storage;
+
+namespace DotNetSolutionTools.App.Services;
+
+public class FileService
+{
+ public async Task DoOpenFilePickerAsync()
+ {
+ if (
+ Application.Current?.ApplicationLifetime
+ is not IClassicDesktopStyleApplicationLifetime desktop
+ || desktop.MainWindow?.StorageProvider is not { } provider
+ )
+ throw new NullReferenceException("Missing StorageProvider instance.");
+
+ var files = await provider.OpenFilePickerAsync(
+ new FilePickerOpenOptions() { Title = "Open Text File", AllowMultiple = false }
+ );
+
+ return files?.Count >= 1 ? files[0] : null;
+ }
+
+ public async Task DoOpenFolderPickerAsync()
+ {
+ if (
+ Application.Current?.ApplicationLifetime
+ is not IClassicDesktopStyleApplicationLifetime desktop
+ || desktop.MainWindow?.StorageProvider is not { } provider
+ )
+ throw new NullReferenceException("Missing StorageProvider instance.");
+
+ var folder = await provider.OpenFolderPickerAsync(
+ new FolderPickerOpenOptions() { Title = "Open Text File", AllowMultiple = false }
+ );
+
+ return folder?.Count >= 1 ? folder[0] : null;
+ }
+}
diff --git a/DotNetSolutionTools.App/ViewModels/MainWindowViewModel.cs b/DotNetSolutionTools.App/ViewModels/MainWindowViewModel.cs
index 0deac88..192c451 100644
--- a/DotNetSolutionTools.App/ViewModels/MainWindowViewModel.cs
+++ b/DotNetSolutionTools.App/ViewModels/MainWindowViewModel.cs
@@ -1,21 +1,15 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.IO;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using Avalonia;
-using Avalonia.Controls.ApplicationLifetimes;
-using Avalonia.Platform.Storage;
+using System.Collections.ObjectModel;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
+using DotNetSolutionTools.App.Services;
using DotNetSolutionTools.Core;
namespace DotNetSolutionTools.App.ViewModels;
public partial class MainWindowViewModel : ViewModelBase
{
+ private readonly FileService _fileService = new();
+
[ObservableProperty]
private string _solutionFolderPath;
@@ -23,33 +17,57 @@ public partial class MainWindowViewModel : ViewModelBase
private string _solutionFilePath;
[ObservableProperty]
- private string? _fileText;
+ private string _csprojFilePath;
[ObservableProperty]
- private ObservableCollection _parityResults = new ObservableCollection()
- {
- "Test"
- };
+ private ObservableCollection _parityResults = new() { };
[RelayCommand]
private async Task ExecuteParityChecker(CancellationToken token)
{
- var results =
- DotNetSolutionTools.Core.SolutionParityChecker.CompareSolutionAndCSharpProjects(
- SolutionFolderPath,
- SolutionFilePath
- );
+ var results = SolutionProjectParity.CompareSolutionAndCSharpProjects(
+ SolutionFolderPath,
+ SolutionFilePath
+ );
ParityResults.Clear();
foreach (var result in results)
- {
ParityResults.Add(result);
- }
}
[RelayCommand]
private async Task FormatCsProjFile(CancellationToken token)
{
- FormatCsproj.FormatCsprojFile(SolutionFilePath);
+ FormatCsproj.FormatCsprojFile(CsprojFilePath);
+ }
+
+ [RelayCommand]
+ private async Task FormatAllCsprojFilesInSolutionFile(CancellationToken token)
+ {
+ var csprojList = SolutionProjectParity.RetrieveAllCSharpProjectFullPathsFromFolder(
+ SolutionFolderPath
+ );
+ foreach (var csproj in csprojList)
+ {
+ FormatCsproj.FormatCsprojFile(csproj);
+ }
+ }
+
+ [RelayCommand]
+ private async Task FormatAllCsprojFilesInSolutionFolder(CancellationToken token)
+ {
+ var csprojList = SolutionProjectParity.RetrieveAllCSharpProjectFullPathsFromFolder(
+ SolutionFolderPath
+ );
+ foreach (var csproj in csprojList)
+ {
+ FormatCsproj.FormatCsprojFile(csproj);
+ }
+ }
+
+ [RelayCommand]
+ private async Task CheckForMissingImplicitUsingsInSolutionFile(CancellationToken token)
+ {
+ ImplicitUsings.FindCSharpProjectsMissingImplicitUsings(SolutionFilePath);
}
[RelayCommand]
@@ -58,7 +76,7 @@ public partial class MainWindowViewModel : ViewModelBase
ErrorMessages?.Clear();
try
{
- var file = await DoOpenFilePickerAsync();
+ var file = await _fileService.DoOpenFilePickerAsync();
if (file is null)
return;
@@ -70,13 +88,19 @@ public partial class MainWindowViewModel : ViewModelBase
}
}
+ [RelayCommand]
+ private async Task ClearSolutionFile(CancellationToken token)
+ {
+ SolutionFilePath = string.Empty;
+ }
+
[RelayCommand]
private async Task LoadSolutionFolder(CancellationToken token)
{
ErrorMessages?.Clear();
try
{
- var folder = await DoOpenFolderPickerAsync();
+ var folder = await _fileService.DoOpenFolderPickerAsync();
if (folder is null)
return;
@@ -88,49 +112,33 @@ public partial class MainWindowViewModel : ViewModelBase
}
}
- private async Task DoOpenFilePickerAsync()
+ [RelayCommand]
+ private async Task ClearSolutionFolder(CancellationToken token)
{
- // For learning purposes, we opted to directly get the reference
- // for StorageProvider APIs here inside the ViewModel.
-
- // For your real-world apps, you should follow the MVVM principles
- // by making service classes and locating them with DI/IoC.
-
- // See IoCFileOps project for an example of how to accomplish this.
- if (
- Application.Current?.ApplicationLifetime
- is not IClassicDesktopStyleApplicationLifetime desktop
- || desktop.MainWindow?.StorageProvider is not { } provider
- )
- throw new NullReferenceException("Missing StorageProvider instance.");
-
- var files = await provider.OpenFilePickerAsync(
- new FilePickerOpenOptions() { Title = "Open Text File", AllowMultiple = false }
- );
-
- return files?.Count >= 1 ? files[0] : null;
+ SolutionFolderPath = string.Empty;
}
- private async Task DoOpenFolderPickerAsync()
+ [RelayCommand]
+ private async Task LoadCsprojFile(CancellationToken token)
{
- // For learning purposes, we opted to directly get the reference
- // for StorageProvider APIs here inside the ViewModel.
+ ErrorMessages?.Clear();
+ try
+ {
+ var folder = await _fileService.DoOpenFilePickerAsync();
+ if (folder is null)
+ return;
- // For your real-world apps, you should follow the MVVM principles
- // by making service classes and locating them with DI/IoC.
+ CsprojFilePath = folder.Path.AbsolutePath;
+ }
+ catch (Exception e)
+ {
+ ErrorMessages?.Add(e.Message);
+ }
+ }
- // See IoCFileOps project for an example of how to accomplish this.
- if (
- Application.Current?.ApplicationLifetime
- is not IClassicDesktopStyleApplicationLifetime desktop
- || desktop.MainWindow?.StorageProvider is not { } provider
- )
- throw new NullReferenceException("Missing StorageProvider instance.");
-
- var folder = await provider.OpenFolderPickerAsync(
- new FolderPickerOpenOptions() { Title = "Open Text File", AllowMultiple = false }
- );
-
- return folder?.Count >= 1 ? folder[0] : null;
+ [RelayCommand]
+ private async Task ClearCsprojFile(CancellationToken token)
+ {
+ CsprojFilePath = string.Empty;
}
}
diff --git a/DotNetSolutionTools.App/ViewModels/PreviewMainWindowViewModel.cs b/DotNetSolutionTools.App/ViewModels/PreviewMainWindowViewModel.cs
new file mode 100644
index 0000000..d831b27
--- /dev/null
+++ b/DotNetSolutionTools.App/ViewModels/PreviewMainWindowViewModel.cs
@@ -0,0 +1,53 @@
+using System.Collections.ObjectModel;
+using CommunityToolkit.Mvvm.ComponentModel;
+using CommunityToolkit.Mvvm.Input;
+
+namespace DotNetSolutionTools.App.ViewModels;
+
+public partial class PreviewMainWindowViewModel : ViewModelBase
+{
+ [ObservableProperty]
+ private string _solutionFolderPath =
+ "C:\\Users\\matt\\source\\repos\\DotNetSolutionTools\\DotNetSolutionTools.App";
+
+ [ObservableProperty]
+ private string _solutionFilePath =
+ "C:\\Users\\matt\\source\\repos\\DotNetSolutionTools\\DotNetSolutionTools.App.sln";
+
+ [ObservableProperty]
+ private string _csprojFilePath =
+ "C:\\Users\\matt\\source\\repos\\DotNetSolutionTools\\DotNetSolutionTools.App.csproj";
+
+ [ObservableProperty]
+ private ObservableCollection _parityResults = new() { "Error Message" };
+
+ [RelayCommand]
+ private async Task ExecuteParityChecker(CancellationToken token)
+ {
+ throw new NotImplementedException();
+ }
+
+ [RelayCommand]
+ private async Task FormatCsProjFile(CancellationToken token)
+ {
+ throw new NotImplementedException();
+ }
+
+ [RelayCommand]
+ private async Task LoadSolutionFile(CancellationToken token)
+ {
+ throw new NotImplementedException();
+ }
+
+ [RelayCommand]
+ private async Task LoadSolutionFolder(CancellationToken token)
+ {
+ throw new NotImplementedException();
+ }
+
+ [RelayCommand]
+ private async Task LoadCsprojFile(CancellationToken token)
+ {
+ throw new NotImplementedException();
+ }
+}
diff --git a/DotNetSolutionTools.App/Views/MainWindow.axaml b/DotNetSolutionTools.App/Views/MainWindow.axaml
index 472c6ba..a1d108b 100644
--- a/DotNetSolutionTools.App/Views/MainWindow.axaml
+++ b/DotNetSolutionTools.App/Views/MainWindow.axaml
@@ -4,27 +4,86 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewModels="clr-namespace:DotNetSolutionTools.App.ViewModels"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
+ Width="800" Height="450"
x:Class="DotNetSolutionTools.App.Views.MainWindow"
x:DataType="viewModels:MainWindowViewModel"
Icon="/Assets/avalonia-logo.ico"
- Title="FileOps">
+ Title="DotNetSolutionTools">
-
- Welcome to Avalonia!
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
\ No newline at end of file
diff --git a/DotNetSolutionTools.CLI/Commands/CompareCommand.cs b/DotNetSolutionTools.CLI/Commands/CompareCommand.cs
index af70e9d..dd601af 100644
--- a/DotNetSolutionTools.CLI/Commands/CompareCommand.cs
+++ b/DotNetSolutionTools.CLI/Commands/CompareCommand.cs
@@ -28,7 +28,7 @@ public class CompareCommand : Command
var pathToSolutionFile = settings.SolutionFilePath;
Console.WriteLine($"Retrieving C# Projects from {folderDirectory}");
- var csprojList = SolutionParityChecker.RetrieveAllCSharpProjectNamesFromFolder(
+ var csprojList = SolutionProjectParity.RetrieveAllCSharpProjectNamesFromFolder(
folderDirectory
);
@@ -45,7 +45,7 @@ public class CompareCommand : Command
Console.WriteLine($"Parsing Solution File: {pathToSolutionFile}");
// Load the solution file
- var solutionFile = SolutionParityChecker.ParseSolutionFileFromPath(pathToSolutionFile);
+ var solutionFile = SolutionProjectParity.ParseSolutionFileFromPath(pathToSolutionFile);
if (solutionFile == null)
{
Console.WriteLine(
@@ -55,7 +55,7 @@ public class CompareCommand : Command
}
// Get the list of projects
- var projectsMissingFromSolution = SolutionParityChecker.FindProjectsMissingFromSolution(
+ var projectsMissingFromSolution = SolutionProjectParity.FindProjectsMissingFromSolution(
csprojList,
solutionFile
);
diff --git a/DotNetSolutionTools.CLI/Commands/FormatCsprojCommand.cs b/DotNetSolutionTools.CLI/Commands/FormatCsprojCommand.cs
index 4c5c195..242599f 100644
--- a/DotNetSolutionTools.CLI/Commands/FormatCsprojCommand.cs
+++ b/DotNetSolutionTools.CLI/Commands/FormatCsprojCommand.cs
@@ -29,7 +29,7 @@ public class FormatCsprojCommand : Command
}
else if (!string.IsNullOrWhiteSpace(settings.SolutionFilePath))
{
- var test = SolutionParityChecker.ParseSolutionFileFromPath(settings.SolutionFilePath);
+ var test = SolutionProjectParity.ParseSolutionFileFromPath(settings.SolutionFilePath);
if (test == null)
{
Console.WriteLine(
@@ -37,7 +37,7 @@ public class FormatCsprojCommand : Command
);
return 1;
}
- var cSharpProjects = SolutionParityChecker.GetCSharpProjectObjectsFromSolutionFile(
+ var cSharpProjects = SolutionProjectParity.GetCSharpProjectObjectsFromSolutionFile(
test
);
Console.WriteLine($"Found {cSharpProjects.Count} C# Projects");
@@ -54,7 +54,7 @@ public class FormatCsprojCommand : Command
var folderDirectory = settings.SolutionFolderPath; // Include the trailing slash
Console.WriteLine($"Retrieving C# Projects from {folderDirectory}");
- var csprojList = SolutionParityChecker.RetrieveAllCSharpProjectFullPathsFromFolder(
+ var csprojList = SolutionProjectParity.RetrieveAllCSharpProjectFullPathsFromFolder(
folderDirectory
);
diff --git a/DotNetSolutionTools.CLI/Commands/ImplicitUsingsCommand.cs b/DotNetSolutionTools.CLI/Commands/ImplicitUsingsCommand.cs
index 0bb05c5..03f306e 100644
--- a/DotNetSolutionTools.CLI/Commands/ImplicitUsingsCommand.cs
+++ b/DotNetSolutionTools.CLI/Commands/ImplicitUsingsCommand.cs
@@ -34,7 +34,7 @@ public class ImplicitUsingsCommand : Command
var pathToSolutionFile = settings.SolutionFilePath;
Console.WriteLine($"Retrieving Solution from {pathToSolutionFile}");
- var solutionFile = SolutionParityChecker.ParseSolutionFileFromPath(pathToSolutionFile);
+ var solutionFile = SolutionProjectParity.ParseSolutionFileFromPath(pathToSolutionFile);
if (solutionFile == null)
{
Console.WriteLine(
@@ -42,7 +42,7 @@ public class ImplicitUsingsCommand : Command
);
return 1;
}
- var cSharpProjects = SolutionParityChecker.GetCSharpProjectObjectsFromSolutionFile(
+ var cSharpProjects = SolutionProjectParity.GetCSharpProjectObjectsFromSolutionFile(
solutionFile
);
Console.WriteLine($"Found {cSharpProjects.Count} C# Projects");
@@ -67,7 +67,7 @@ public class ImplicitUsingsCommand : Command
Console.WriteLine("==================================================");
Console.WriteLine("Adding missing implicit usings");
ImplicitUsings.AddMissingImplicitUsings(projectsMissingImplicitUsings);
- var updatedProjects = SolutionParityChecker.GetCSharpProjectObjectsFromSolutionFile(
+ var updatedProjects = SolutionProjectParity.GetCSharpProjectObjectsFromSolutionFile(
solutionFile
);
var projectsWithMissing = ImplicitUsings.FindCSharpProjectsMissingImplicitUsings(
diff --git a/DotNetSolutionTools.Core/FormatCsproj.cs b/DotNetSolutionTools.Core/FormatCsproj.cs
index 797e9ea..d659582 100644
--- a/DotNetSolutionTools.Core/FormatCsproj.cs
+++ b/DotNetSolutionTools.Core/FormatCsproj.cs
@@ -19,14 +19,13 @@ public static class FormatCsproj
using var wr = new StreamWriter(csprojFilePath, false, Encoding.Default);
- var settings =
- new XmlWriterSettings
- {
- Indent = true,
- IndentChars = "\t",
- NewLineOnAttributes = false,
- OmitXmlDeclaration = true
- };
+ var settings = new XmlWriterSettings
+ {
+ Indent = true,
+ IndentChars = "\t",
+ NewLineOnAttributes = false,
+ OmitXmlDeclaration = true
+ };
using (var writer = XmlWriter.Create(wr, settings))
{
@@ -34,4 +33,4 @@ public static class FormatCsproj
writer.Close();
}
}
-}
\ No newline at end of file
+}
diff --git a/DotNetSolutionTools.Core/ImplicitUsings.cs b/DotNetSolutionTools.Core/ImplicitUsings.cs
index 2b6be75..4214525 100644
--- a/DotNetSolutionTools.Core/ImplicitUsings.cs
+++ b/DotNetSolutionTools.Core/ImplicitUsings.cs
@@ -4,10 +4,26 @@ namespace DotNetSolutionTools.Core;
public static class ImplicitUsings
{
- public static List FindCSharpProjectsMissingImplicitUsings(List projectList)
+ public static List FindCSharpProjectsMissingImplicitUsings(string solutionFilePath)
+ {
+ var solutionFile = SolutionFile.Parse(solutionFilePath);
+ var csprojList = SolutionProjectParity.GetCSharpProjectObjectsFromSolutionFile(
+ solutionFile
+ );
+ var projectsMissingImplicitUsings = FindCSharpProjectsMissingImplicitUsings(csprojList);
+ var projectsMissingImplicitUsingsStringList = projectsMissingImplicitUsings
+ .Select(x => x.FullPath)
+ .ToList();
+
+ return projectsMissingImplicitUsingsStringList;
+ }
+
+ public static List FindCSharpProjectsMissingImplicitUsings(
+ List projectList
+ )
{
var projectsMissingImplicitUsings = new List();
-
+
foreach (var project in projectList)
{
var implicitUsings = project.PropertyGroups
@@ -22,7 +38,9 @@ public static class ImplicitUsings
return projectsMissingImplicitUsings;
}
- public static void AddMissingImplicitUsings(List projectsMissingImplicitUsings)
+ public static void AddMissingImplicitUsings(
+ List projectsMissingImplicitUsings
+ )
{
foreach (var project in projectsMissingImplicitUsings)
{
@@ -35,16 +53,20 @@ public static class ImplicitUsings
}
}
- public static void EnableDisabledImplicitUsings(List projectsMissingImplicitUsings)
+ public static void EnableDisabledImplicitUsings(
+ List projectsMissingImplicitUsings
+ )
{
throw new NotImplementedException();
}
- public static void EnableAllImplicitUsings(List projectsMissingImplicitUsings)
+ public static void EnableAllImplicitUsings(
+ List projectsMissingImplicitUsings
+ )
{
throw new NotImplementedException();
}
-
+
public static bool ProjectIsMissingImplicitUsings(ProjectRootElement project)
{
var implicitUsings = project.PropertyGroups
@@ -57,4 +79,4 @@ public static class ImplicitUsings
return false;
}
-}
\ No newline at end of file
+}
diff --git a/DotNetSolutionTools.Core/SolutionParityChecker.cs b/DotNetSolutionTools.Core/SolutionProjectParity.cs
similarity index 98%
rename from DotNetSolutionTools.Core/SolutionParityChecker.cs
rename to DotNetSolutionTools.Core/SolutionProjectParity.cs
index 47d1e2d..24a9dfa 100644
--- a/DotNetSolutionTools.Core/SolutionParityChecker.cs
+++ b/DotNetSolutionTools.Core/SolutionProjectParity.cs
@@ -2,7 +2,7 @@
namespace DotNetSolutionTools.Core;
-public static class SolutionParityChecker
+public static class SolutionProjectParity
{
public static List CompareSolutionAndCSharpProjects(
string solutionFolderPath,