Windows-XAML/Template10

Discuss: extend Template10.Service.File

jp-weber opened this issue · 5 comments

I wonder if it makes sense to extend the file service so that you can also choose user-defined paths. Here, however, is the problem that depending on the permission granted (folder or file) different methods have to be taken.

The question I ask myself, how can this be made visible to users in a simple way?

In my fork I use for my app, I have already done this. For example:
https://github.com/jp-weber/Template10/blob/master/Source/Template10.Extras.10586/Services/File/Abstractions/IFileService.cs

I think we could overload things and do just that.

I don't know what's the right thing to do. I have been working with StorageFiles for so long now that it doesn't even seem like they need a helper anymore. That said, I wonder if we want to create a general FileIO interface with a FileAdapter, WinRTAdapter, AzureBlobAdapter, AzureFileAdapter, and maybe even OneDriveAdapter.

Could we use FileIO and System.IO as a starter?

public static interface FileIO
{
    Task<string> ReadTextAsync(IStorageFile file);
    Task<string> ReadTextAsync(IStorageFile file, UnicodeEncoding encoding);
    Task WriteTextAsync(IStorageFile file, string contents);
    Task WriteTextAsync(IStorageFile file, string contents, UnicodeEncoding encoding);
    Task AppendTextAsync(IStorageFile file, string contents);
    Task AppendTextAsync(IStorageFile file, string contents, UnicodeEncoding encoding);
    Task<IList<string>> ReadLinesAsync(IStorageFile file);
    Task<IList<string>> ReadLinesAsync(IStorageFile file, UnicodeEncoding encoding);
    Task WriteLinesAsync(IStorageFile file, IEnumerable<string> lines);
    Task WriteLinesAsync(IStorageFile file, IEnumerable<string> lines, UnicodeEncoding encoding);
    Task AppendLinesAsync(IStorageFile file, IEnumerable<string> lines);
    Task AppendLinesAsync(IStorageFile file, IEnumerable<string> lines, UnicodeEncoding encoding);
    Task<Stream> ReadStreamAsync(IStorageFile file);
    Task WriteStreamAsync(IStorageFile file, Stream stream);
    Task WriteBytesAsync(IStorageFile file, byte[] bytes);
}

and

public interface IStorageFolder : IStorageItem
{
    Task<StorageFile> CreateFileAsync(string desiredName);
    Task<StorageFile> CreateFileAsync(string desiredName, CreationCollisionOption options);
    Task<StorageFolder> CreateFolderAsync(string desiredName);
    Task<StorageFolder> CreateFolderAsync(string desiredName, CreationCollisionOption options);
    Task<StorageFile> GetFileAsync(string name);
    Task<StorageFolder> GetFolderAsync(string name);
    Task<IStorageItem> GetItemAsync(string name);
    Task<IReadOnlyList<StorageFile>> GetFilesAsync();
    Task<IReadOnlyList<StorageFolder>> GetFoldersAsync();
    Task<IReadOnlyList<IStorageItem>> GetItemsAsync();
}

and

public interface IStorageFile : IStorageItem
{
    Task<IRandomAccessStream> OpenAsync(FileAccessMode accessMode);
    Task<StorageStreamTransaction> OpenTransactedWriteAsync();
    Task<StorageFile> CopyAsync(IStorageFolder destinationFolder);
    Task<StorageFile> CopyAsync(IStorageFolder destinationFolder, string desiredNewName);
    Task<StorageFile> CopyAsync(IStorageFolder destinationFolder, string desiredNewName, NameCollisionOption option);
    Task CopyAndReplaceAsync(IStorageFile fileToReplace);
    Task MoveAsync(IStorageFolder destinationFolder);
    Task MoveAsync(IStorageFolder destinationFolder, string desiredNewName);
    Task MoveAsync(IStorageFolder destinationFolder, string desiredNewName, NameCollisionOption option);
    Task MoveAndReplaceAsync(IStorageFile fileToReplace);
    string ContentType { get; }
    string FileType { get; }
}

and

public static class Directory
{
    public static DirectoryInfo CreateDirectory(string path);
    public static void Delete(string path);
    public static void Delete(string path, bool recursive);
    public static IEnumerable<string> EnumerateDirectories(string path);
    public static IEnumerable<string> EnumerateDirectories(string path, string searchPattern);
    public static IEnumerable<string> EnumerateDirectories(string path, string searchPattern, SearchOption searchOption);
    public static IEnumerable<string> EnumerateFiles(string path);
    public static IEnumerable<string> EnumerateFiles(string path, string searchPattern);
    public static IEnumerable<string> EnumerateFiles(string path, string searchPattern, SearchOption searchOption);
    public static IEnumerable<string> EnumerateFileSystemEntries(string path, string searchPattern, SearchOption searchOption);
    public static IEnumerable<string> EnumerateFileSystemEntries(string path);
    public static IEnumerable<string> EnumerateFileSystemEntries(string path, string searchPattern);
    public static bool Exists(string path);
    public static DateTime GetCreationTime(string path);
    public static DateTime GetCreationTimeUtc(string path);
    public static string GetCurrentDirectory();
    public static string[] GetDirectories(string path, string searchPattern);
    public static string[] GetDirectories(string path);
    public static string[] GetDirectories(string path, string searchPattern, SearchOption searchOption);
    public static string GetDirectoryRoot(string path);
    public static string[] GetFiles(string path);
    public static string[] GetFiles(string path, string searchPattern);
    public static string[] GetFiles(string path, string searchPattern, SearchOption searchOption);
    public static string[] GetFileSystemEntries(string path);
    public static string[] GetFileSystemEntries(string path, string searchPattern);
    public static string[] GetFileSystemEntries(string path, string searchPattern, SearchOption searchOption);
    public static DateTime GetLastAccessTime(string path);
    public static DateTime GetLastAccessTimeUtc(string path);
    public static DateTime GetLastWriteTime(string path);
    public static DateTime GetLastWriteTimeUtc(string path);
    public static string[] GetLogicalDrives();
    public static DirectoryInfo GetParent(string path);
    public static void Move(string sourceDirName, string destDirName);
    public static void SetCreationTime(string path, DateTime creationTime);
    public static void SetCreationTimeUtc(string path, DateTime creationTimeUtc);
    public static void SetCurrentDirectory(string path);
    public static void SetLastAccessTime(string path, DateTime lastAccessTime);
    public static void SetLastAccessTimeUtc(string path, DateTime lastAccessTimeUtc);
    public static void SetLastWriteTime(string path, DateTime lastWriteTime);
    public static void SetLastWriteTimeUtc(string path, DateTime lastWriteTimeUtc);
}

and

public static class File
{
    public static void AppendAllLines(string path, IEnumerable<string> contents);
    public static void AppendAllLines(string path, IEnumerable<string> contents, Encoding encoding);
    public static Task AppendAllLinesAsync(string path, IEnumerable<string> contents, CancellationToken cancellationToken = default);
    public static Task AppendAllLinesAsync(string path, IEnumerable<string> contents, Encoding encoding, CancellationToken cancellationToken = default);
    public static void AppendAllText(string path, string contents);
    public static void AppendAllText(string path, string contents, Encoding encoding);
    public static Task AppendAllTextAsync(string path, string contents, CancellationToken cancellationToken = default);
    public static Task AppendAllTextAsync(string path, string contents, Encoding encoding, CancellationToken cancellationToken = default);
    public static StreamWriter AppendText(string path);
    public static void Copy(string sourceFileName, string destFileName);
    public static void Copy(string sourceFileName, string destFileName, bool overwrite);
    public static FileStream Create(string path);
    public static FileStream Create(string path, int bufferSize);
    public static FileStream Create(string path, int bufferSize, FileOptions options);
    public static StreamWriter CreateText(string path);
    public static void Decrypt(string path);
    public static void Delete(string path);
    public static void Encrypt(string path);
    public static bool Exists(string path);
    public static FileAttributes GetAttributes(string path);
    public static DateTime GetCreationTime(string path);
    public static DateTime GetCreationTimeUtc(string path);
    public static DateTime GetLastAccessTime(string path);
    public static DateTime GetLastAccessTimeUtc(string path);
    public static DateTime GetLastWriteTime(string path);
    public static DateTime GetLastWriteTimeUtc(string path);
    public static void Move(string sourceFileName, string destFileName);
    public static FileStream Open(string path, FileMode mode);
    public static FileStream Open(string path, FileMode mode, FileAccess access);
    public static FileStream Open(string path, FileMode mode, FileAccess access, FileShare share);
    public static FileStream OpenRead(string path);
    public static StreamReader OpenText(string path);
    public static FileStream OpenWrite(string path);
    public static byte[] ReadAllBytes(string path);
    public static Task<byte[]> ReadAllBytesAsync(string path, CancellationToken cancellationToken = default);
    public static string[] ReadAllLines(string path);
    public static string[] ReadAllLines(string path, Encoding encoding);
    public static Task<string[]> ReadAllLinesAsync(string path, CancellationToken cancellationToken = default);
    public static Task<string[]> ReadAllLinesAsync(string path, Encoding encoding, CancellationToken cancellationToken = default);
    public static string ReadAllText(string path);
    public static string ReadAllText(string path, Encoding encoding);
    public static Task<string> ReadAllTextAsync(string path, CancellationToken cancellationToken = default);
    public static Task<string> ReadAllTextAsync(string path, Encoding encoding, CancellationToken cancellationToken = default);
    public static IEnumerable<string> ReadLines(string path);
    public static IEnumerable<string> ReadLines(string path, Encoding encoding);
    public static void Replace(string sourceFileName, string destinationFileName, string destinationBackupFileName);
    public static void Replace(string sourceFileName, string destinationFileName, string destinationBackupFileName, bool ignoreMetadataErrors);
    public static void SetAttributes(string path, FileAttributes fileAttributes);
    public static void SetCreationTime(string path, DateTime creationTime);
    public static void SetCreationTimeUtc(string path, DateTime creationTimeUtc);
    public static void SetLastAccessTime(string path, DateTime lastAccessTime);
    public static void SetLastAccessTimeUtc(string path, DateTime lastAccessTimeUtc);
    public static void SetLastWriteTime(string path, DateTime lastWriteTime);
    public static void SetLastWriteTimeUtc(string path, DateTime lastWriteTimeUtc);
    public static void WriteAllBytes(string path, byte[] bytes);
    public static Task WriteAllBytesAsync(string path, byte[] bytes, CancellationToken cancellationToken = default);
    public static void WriteAllLines(string path, string[] contents);
    public static void WriteAllLines(string path, IEnumerable<string> contents);
    public static void WriteAllLines(string path, string[] contents, Encoding encoding);
    public static void WriteAllLines(string path, IEnumerable<string> contents, Encoding encoding);
    public static Task WriteAllLinesAsync(string path, IEnumerable<string> contents, CancellationToken cancellationToken = default);
    public static Task WriteAllLinesAsync(string path, IEnumerable<string> contents, Encoding encoding, CancellationToken cancellationToken = default);
    public static void WriteAllText(string path, string contents);
    public static void WriteAllText(string path, string contents, Encoding encoding);
    public static Task WriteAllTextAsync(string path, string contents, CancellationToken cancellationToken = default);
    public static Task WriteAllTextAsync(string path, string contents, Encoding encoding, CancellationToken cancellationToken = default);
}

I don't think we need this in the first release of T10.2. Maybe later

Thank you for saying that. I agree.

I agree. It would just be too much. We should stick with the most useful case and perhaps extend it in this way:

Task<bool> DeleteFileAsync(string key, StorageStrategies location = StorageStrategies.Local, string path = null);

Task<bool> DeleteFileAsync(string key, StorageFolder folder);

Task<bool> FileExistsAsync(string key, StorageStrategies location = StorageStrategies.Local, string path = null);

Task<bool> FileExistsAsync(string key, StorageFolder folder);

Task<T> ReadFileAsync<T>(string key, StorageStrategies location = StorageStrategies.Local, string path = null);

Task<T> ReadFileAsync<T>(string key, StorageFolder folder);

Task<string> ReadStringAsync(string key, StorageStrategies location = StorageStrategies.Local, string path = null);

Task<string> ReadStringAsync(string key, StorageFolder folder);

Task<bool> WriteFileAsync<T>(string key, T value, StorageStrategies location = StorageStrategies.Local, CreationCollisionOption option = CreationCollisionOption.ReplaceExisting, string path = null);

Task<bool> WriteFileAsync<T>(string key, T value, StorageFolder folder);

Task<bool> WriteStringAsync(string key, string value, StorageStrategies location = StorageStrategies.Local, CreationCollisionOption option = CreationCollisionOption.ReplaceExisting, string path = null);

See https://github.com/jp-weber/Template10/blob/80b338094fc50b41e4621ced8bb3412ea006c691/Source/Template10.Extras/Services/File/Abstractions/IFileService.cs