[API Proposal]: Microsoft.Extensions.FileProviders.Physical.PhysicalFilesWatcher should expose modified files (Alternative where standalone FilesystemWatcher won't work)
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 25/100
- Issue type
- Feature
- Clarity
- Needs clarification
- Activity status
- Stale
- Tech stack
- csharp
- Domain
- backend-api-design
Research direction
Start by reading the existing PhysicalFilesWatcher, PollingFileChangeToken, IPollingChangeToken, and IChangeToken contracts, then review the concerns and prior discussion referenced in #17111. Done means reaching a concrete, maintainable API direction for exposing changed file information, with its compatibility, performance, and information-hiding tradeoffs resolved.
Written by the indexing model from the issue text.
Description
Background and motivation
Currently, PhysicalFileProvider provides a configurable file modification detector via PhysicalFilesWatcher wrapped by FilesystemWatcher and offers a polling feature on request (either by API or via environment variables).
Unfortunately, IChangeToken hides file path information of the actual file changes to API user/client code. While information hiding is a quite common design technique, file path information may become quite useful for API users, especially when polling is the only option available to achieve modification tracking/observation and a fallback to a custom implementation based on (good-old) FilesystemWatcher is not an option.
Please consider to either enhance IPollingChangeToken to expose (physical) FileInfo or provide an extra IChangeToken which exposes file paths for all behaviors implemented in PhysicalFilesWatcher.
API Proposal
namespace Microsoft.Extensions.FileProviders.Physical
{
public class PollingFileChangeToken : IPollingChangeToken
{
private readonly FileInfo _fileInfo;
private DateTime _previousWriteTimeUtc;
private DateTime _lastCheckedTimeUtc;
private bool _hasChanged;
private CancellationTokenSource? _tokenSource;
private CancellationChangeToken? _changeToken;
public PollingFileChangeToken(FileInfo fileInfo)
{
_fileInfo = fileInfo;
_previousWriteTimeUtc = GetLastWriteTimeUtc();
}
public IFileInfo FileInfo => __fileInfo ;
}
API Usage
PhysicalFileProviderfileProvider = new (Directory.GetCurrentDirectory());
CompositeChangeToken token = fileProvider.Watch(_fileFilter) as CompositeChangeToken ;
ConcurrentQueue<IFileInfo> changeList = new ();
token.RegisterChangeCallback(state =>
{
IFileInfo[] modifcationList = token.ChangeTokens
.Cast<PollingFileChangeToken>()
.Select(token => token.FileInfo )
.ToArray();
} , default);
Drawback: This approch might not be perfomant. Neither it provides an elegant solution.
Alternative Designs
Alternativly please consider to extract polling feature as an independent (refactored/extracted) PollingFilesystemWatcher which offfers either customized IChangeToken or Rx.NET support if changing information hiding policy here violates IChangeToken concept or any SOLID principle , I might have missed in my orginal propoals (due to lack of insight and/or overview of your orginal design consideration and usage).
namespace Microsoft.Extensions.FileProviders.Physical
{
/// <summary>
/// Watches a physical file system for changes and triggers events on
/// <see cref="IChangeToken" /> when files are created, change, renamed, or deleted.
/// </summary>
public class PhysicalFilesWatcher : IDisposable
{
public IObserable<IFileInfo> WhenFileSystemEntryChange()
}
Or
namespace Microsoft.Extensions.FileProviders
{
public interface IFileChangeToken : IChangeToken
{
public IFileInfo RootPath { get; }
IDisposable RegisterChangeCallback(Action<IFileInfo?> callback, object? state);
}
}
namespace Microsoft.Extensions.FileProviders.Physical
{
/// <summary>
/// Watches a physical file system for changes and triggers events on
/// <see cref="IChangeToken" /> when files are created, change, renamed, or deleted.
/// </summary>
public class PhysicalFilesWatcher : IDisposable
{
public IFileChangeToken Start()
}
MIght Pick up some ideas already discussed in #17111
Risks
- Violation of information hiding policy or intended contracts
- Violoation of even more SOLID principles by just exposing
IFileInfowhen extraction and adding another level of abstraction might offer a more plausbile and solid concept - API suggestion (currently) neither elegant nor performant
- Dominant language
- C#
- Stars
- 18.3k
- Forks
- 5.6k
- PR merge metrics
- PR metrics pending
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from dotnet/runtime
-
agentic-workflows untriaged
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
-
area-System.Reflection blocking-clean-ci-optional Known Build Error os-mac-os-x untriaged
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
area-CodeGen-coreclr untriaged
Difficulty 1/5 Under an hour Newbie friendliness 92/100
-
agentic-workflows untriaged
Difficulty 1/5 Under an hour Newbie friendliness 78/100
-
area-VM-meta-mono untriaged
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
-
:watch: Not Triaged 11.0 fundamentals/subsvc
Difficulty 2/5 1-3 hours Newbie friendliness 92/100
dotnet/AspNetCore.Docs#37699 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
SubtitleEdit/subtitleedit#15108 · 1 comment ·
-
area/docs-content Bug pulumi/docs
Difficulty 1/5 1-3 hours Newbie friendliness 94/100
-
Create parent directories only after the containment check in InstallHelper.TryExtractToDirectory Open
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
PowerShell/PSResourceGet#2056 ·