![]() |
VOOZH | about |
dotnet add package DoenaSoft.AbstractionLayer.IO.Default --version 2.0.6
NuGet\Install-Package DoenaSoft.AbstractionLayer.IO.Default -Version 2.0.6
<PackageReference Include="DoenaSoft.AbstractionLayer.IO.Default" Version="2.0.6" />
<PackageVersion Include="DoenaSoft.AbstractionLayer.IO.Default" Version="2.0.6" />Directory.Packages.props
<PackageReference Include="DoenaSoft.AbstractionLayer.IO.Default" />Project file
paket add DoenaSoft.AbstractionLayer.IO.Default --version 2.0.6
#r "nuget: DoenaSoft.AbstractionLayer.IO.Default, 2.0.6"
#:package DoenaSoft.AbstractionLayer.IO.Default@2.0.6
#addin nuget:?package=DoenaSoft.AbstractionLayer.IO.Default&version=2.0.6Install as a Cake Addin
#tool nuget:?package=DoenaSoft.AbstractionLayer.IO.Default&version=2.0.6Install as a Cake Tool
Default System.IO-based implementations of the file I/O abstraction interfaces defined in DoenaSoft.AbstractionLayer.IO. This package provides production-ready file system operations for .NET Standard 2.0, .NET Framework 4.7.2, and .NET 10.
Package Id: DoenaSoft.AbstractionLayer.IO.Default
Targets: netstandard2.0, net472, net10.0
This package contains the default implementations that wrap System.IO classes to implement the interfaces from DoenaSoft.AbstractionLayer.IO. Use this package in production code to perform actual file system operations.
Dependencies:
DoenaSoft.AbstractionLayer.IO - Contains the interface contractsLicense: MIT
This package provides concrete System.IO-based implementations:
IOServices - Default implementation of IIOServices. Aggregates all I/O services and provides factory methods.File - Wraps System.IO.File static methodsFileInfo - Wraps System.IO.FileInfo instance methodsPath - Wraps System.IO.Path static methodsFolder - Wraps System.IO.Directory static methodsFolderInfo - Wraps System.IO.DirectoryInfo instance methodsDriveInfo - Wraps System.IO.DriveInfoFileSystemWatcher - Wraps System.IO.FileSystemWatcherConsoleLogger - Writes I/O operations to consoleFileLogger - Writes I/O operations to a fileDualLogger - Combines two loggers (e.g., console + file)RenameQueue - Manages file rename operationsInstall both packages:
Install-Package DoenaSoft.AbstractionLayer.IO
Install-Package DoenaSoft.AbstractionLayer.IO.Default
Use the default implementations in production code:
using DoenaSoft.AbstractionLayer.IOServices;
// Create the default IOServices instance
var io = new IOServices();
// Use the file operations
if (io.File.Exists("data.txt"))
{
var content = io.File.ReadAllText("data.txt");
}
// Use folder operations
var folder = io.GetFolder(@"C:\MyData");
foreach (var file in folder.GetFiles("*.txt"))
{
Console.WriteLine(file.Name);
}
// Use path operations
var combined = io.Path.Combine("folder", "subfolder", "file.txt");
The implementations support optional logging to track I/O operations:
using DoenaSoft.AbstractionLayer.IOServices;
// Create logger (optional)
var logger = new ConsoleLogger();
// or log to file
var fileLogger = new FileLogger("operations.log");
// or combine both
var dualLogger = new DualLogger(new ConsoleLogger(), new FileLogger("ops.log"));
// Create IOServices with logger
var io = new IOServices(dualLogger);
// File operations will be logged
io.File.Copy("source.txt", "dest.txt");
// Console/file output: "Copy file "source.txt""
// "to "dest.txt""
Inject IIOServices into your classes for testability:
public class DataProcessor
{
private readonly IIOServices _io;
public DataProcessor(IIOServices io)
{
_io = io;
}
public void ProcessFiles(string folder)
{
var folderInfo = _io.GetFolder(folder);
foreach (var file in folderInfo.GetFiles("*.dat"))
{
var content = _io.File.ReadAllBytes(file.FullName);
// process content
}
}
}
// In production (e.g., Program.cs or Startup.cs)
services.AddSingleton<IIOServices, IOServices>();
// In unit tests
var fakeIO = new FakeIOServices();
var processor = new DataProcessor(fakeIO);
The RenameQueue class provides advanced mass rename operations with automatic rollback and progress reporting:
using DoenaSoft.AbstractionLayer.IOServices;
var io = new IOServices();
// Create rename queue with optional logger
var renameQueue = new RenameQueue(io, new ConsoleLogger());
// Initialize and add files
renameQueue.Initialize();
renameQueue.Add("old1.txt", "new1.txt");
renameQueue.Add("old2.txt", "new2.txt");
renameQueue.Add("old3.txt", "new3.txt");
// Create progress reporter
var progress = new Progress<IRenameProgress>(p =>
{
Console.WriteLine($"Renaming: {p.Completed}/{p.Total} ({p.PercentComplete:F1}%)");
if (p.CurrentSourceFile != null)
{
Console.WriteLine($" {p.CurrentSourceFile} -> {p.CurrentTargetFile}");
}
});
// Commit with automatic rollback (default)
var result = renameQueue.Commit(RenameRollbackBehaviour.Automatic, progress);
if (result.Success)
{
Console.WriteLine($"Successfully renamed {result.SuccessCount} files:");
foreach (var (source, target) in result.SuccessfulRenames)
{
Console.WriteLine($" {source} -> {target}");
}
}
else
{
Console.WriteLine($"Rename failed: {result.ErrorMessage}");
if (result.RolledBack)
{
Console.WriteLine($"All {result.RolledBackCount} completed renames were rolled back.");
Console.WriteLine("All files are in their original state.");
}
Console.WriteLine($"Failed files ({result.FailedRenames.Count}):");
foreach (var (source, target, error) in result.FailedRenames)
{
Console.WriteLine($" {source} -> {target}: {error}");
}
if (result.RollbackErrors.Count > 0)
{
Console.WriteLine($"Rollback errors ({result.RollbackErrors.Count}):");
foreach (var error in result.RollbackErrors)
{
Console.WriteLine($" {error}");
}
}
}
Automatic (default):
FailedRenames listSuccessfulRenames will be emptyManual:
None:
// Example with Manual rollback
var result = renameQueue.Commit(RenameRollbackBehaviour.Manual, progress);
if (!result.Success)
{
Console.WriteLine($"{result.SuccessCount} files renamed successfully before error");
Console.WriteLine($"{result.FailedRenames.Count} files failed");
// Optionally retry failed files or manually rollback successful ones
}
DoenaSoft.AbstractionLayer.IO (contracts) and create test doublesDoenaSoft.AbstractionLayer.IO - Interface contracts (required)DoenaSoft.AbstractionLayer.IO.Default (this package) - System.IO-based implementationsILoggerFileSystemWatcher implementation properly wraps System.IO.FileSystemWatcher eventsPackage Id: DoenaSoft.AbstractionLayer.IO
Targets: netstandard2.0, net472, net10.0
Usage:
Use the provided interfaces when writing code that performs file operations so you can inject test doubles in unit tests.
License: MIT
The project provides several interfaces that represent parts of the file system. The primary entry point is IIOServices and the contracts include:
IIOServices - The main entry point that aggregates access to all I/O services. Provides factory methods for files, folders, drives, and file system watchers.IIOServiceItem - Base interface for all types that provide access to the master IIOServices interface. All file system-related interfaces inherit from this.IPath - Provides path manipulation helpers (combine, get extension, get folder name, change extension, etc.)IFile - Static file operations (exists, copy, move, delete, read all bytes/lines/text, write all bytes/lines/text, append, open streams, get/set attributes and timestamps, replace, etc.)IFileInfo - Instance-based file operations and metadata (name, extension, full name, folder, size, attributes, timestamps, exists, copy, move, delete, open streams, create text, etc.)IFolder - Static folder operations (exists, create, delete, get files/folders, move, get/set current folder, get parent, etc.)IFolderInfo - Instance-based folder operations and metadata (name, full name, parent, root, drive, attributes, timestamps, exists, create, delete, move, get files/folders, etc.)IDriveInfo - Drive-specific information (name, drive type, drive format, drive letter, volume label, ready state, available free space, total free space, total size, root folder, etc.)IFileSystemWatcher - File system change notification abstraction with events for file creation, deletion, and renaming.ILogger - Logging abstraction used by implementations to record I/O operations.IRenameQueue - Queue abstraction for managing file rename operations.IShortcut - Abstraction for creating and managing file shortcuts with description, target path, and working folder.IIOServices is intended as the primary entry point in application code; it is typically implemented with a thin wrapper around System.IO in production and with an in-memory fake in tests.
Testing benefits
IIOServices fake during tests to avoid touching the disk and to deterministically set up file state.Examples
Usage from application code:
public class FileProcessor
{
private readonly DoenaSoft.AbstractionLayer.IOServices.IIOServices _io;
public FileProcessor(DoenaSoft.AbstractionLayer.IOServices.IIOServices io)
{
_io = io;
}
public string ReadFirstLine(string path)
{
using var stream = _io.GetFileStream(path, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read);
using var reader = new System.IO.StreamReader(stream);
return reader.ReadLine();
}
}
Simple fake for unit tests (illustrative, implement additional members as required):
class FakeFileStream : System.IO.MemoryStream { }
class FakeFile : DoenaSoft.AbstractionLayer.IOServices.IFile
{
public bool Exists(string fileName) => true;
// ... implement other IFile members used by your code
}
class FakeIIOServices : DoenaSoft.AbstractionLayer.IOServices.IIOServices
{
public DoenaSoft.AbstractionLayer.IOServices.IPath Path => throw new System.NotImplementedException();
public DoenaSoft.AbstractionLayer.IOServices.IFile File => new FakeFile();
public DoenaSoft.AbstractionLayer.IOServices.IFolder Folder => throw new System.NotImplementedException();
public DoenaSoft.AbstractionLayer.IOServices.IFolderInfo GetFolder(string folder) => throw new System.NotImplementedException();
public DoenaSoft.AbstractionLayer.IOServices.IFileInfo GetFile(string fileName) => throw new System.NotImplementedException();
public System.IO.Stream GetFileStream(string fileName, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share)
{
// Return a memory stream containing test data
var ms = new FakeFileStream();
var writer = new System.IO.StreamWriter(ms);
writer.WriteLine("first line");
writer.Flush();
ms.Position = 0;
return ms;
}
public System.Collections.Generic.IEnumerable<DoenaSoft.AbstractionLayer.IOServices.IDriveInfo> GetDrives(System.IO.DriveType? driveType = null) => System.Array.Empty<DoenaSoft.AbstractionLayer.IOServices.IDriveInfo>();
public DoenaSoft.AbstractionLayer.IOServices.IDriveInfo GetDrive(string driveLetter) => throw new System.NotImplementedException();
public DoenaSoft.AbstractionLayer.IOServices.IFileSystemWatcher GetFileSystemWatcher(string folder, string searchPattern = "*.*") => throw new System.NotImplementedException();
}
// In a unit test
var fake = new FakeIIOServices();
var processor = new FileProcessor(fake);
var firstLine = processor.ReadFirstLine("any.txt");
// assert firstLine == "first line"
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 net5.0 was computed. net5.0-windows net5.0-windows was computed. net6.0 net6.0 was computed. net6.0-android net6.0-android was computed. net6.0-ios net6.0-ios was computed. net6.0-maccatalyst net6.0-maccatalyst was computed. net6.0-macos net6.0-macos was computed. net6.0-tvos net6.0-tvos was computed. net6.0-windows net6.0-windows was computed. net7.0 net7.0 was computed. net7.0-android net7.0-android was computed. net7.0-ios net7.0-ios was computed. net7.0-maccatalyst net7.0-maccatalyst was computed. net7.0-macos net7.0-macos was computed. net7.0-tvos net7.0-tvos was computed. net7.0-windows net7.0-windows was computed. net8.0 net8.0 was computed. net8.0-android net8.0-android was computed. net8.0-browser net8.0-browser was computed. net8.0-ios net8.0-ios was computed. net8.0-maccatalyst net8.0-maccatalyst was computed. net8.0-macos net8.0-macos was computed. net8.0-tvos net8.0-tvos was computed. net8.0-windows net8.0-windows was computed. net9.0 net9.0 was computed. net9.0-android net9.0-android was computed. net9.0-browser net9.0-browser was computed. net9.0-ios net9.0-ios was computed. net9.0-maccatalyst net9.0-maccatalyst was computed. net9.0-macos net9.0-macos was computed. net9.0-tvos net9.0-tvos was computed. net9.0-windows net9.0-windows was computed. net10.0 net10.0 is compatible. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 netcoreapp2.0 was computed. netcoreapp2.1 netcoreapp2.1 was computed. netcoreapp2.2 netcoreapp2.2 was computed. netcoreapp3.0 netcoreapp3.0 was computed. netcoreapp3.1 netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 netstandard2.0 is compatible. netstandard2.1 netstandard2.1 was computed. |
| .NET Framework | net461 net461 was computed. net462 net462 was computed. net463 net463 was computed. net47 net47 was computed. net471 net471 was computed. net472 net472 is compatible. net48 net48 was computed. net481 net481 was computed. |
| MonoAndroid | monoandroid monoandroid was computed. |
| MonoMac | monomac monomac was computed. |
| MonoTouch | monotouch monotouch was computed. |
| Tizen | tizen40 tizen40 was computed. tizen60 tizen60 was computed. |
| Xamarin.iOS | xamarinios xamarinios was computed. |
| Xamarin.Mac | xamarinmac xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos xamarinwatchos was computed. |
This package is not used by any NuGet packages.
This package is not used by any popular GitHub repositories.