Skip to content
This repository was archived by the owner on Nov 6, 2018. It is now read-only.

Provide a composite file provider type #114

Closed
kichalla opened this issue Jul 16, 2015 · 1 comment
Closed

Provide a composite file provider type #114

kichalla opened this issue Jul 16, 2015 · 1 comment

Comments

@kichalla
Copy link
Member

I am not sure if its intentional, but I see in few places where we accept a single file provider instance.

https://github.com/aspnet/StaticFiles/blob/dev/src/Microsoft.AspNet.StaticFiles/Infrastructure/SharedOptions.cs#L44
https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNet.Mvc.Razor/RazorViewEngineOptions.cs#L31

If I have files from multiple sources(ex: physical and embedded), is it expected to write my own composite file provider?

My scenario - I was trying to see how a fix for this issue would be.

Example:

public class CompositeFileProvider : IFileProvider
{
    private readonly IEnumerable<IFileProvider> _fileProviders;

    public CompositeFileProvider(IEnumerable<IFileProvider> fileProviders)
    {
        _fileProviders = fileProviders;
    }

    public IDirectoryContents GetDirectoryContents(string subpath)
    {
        foreach (var provider in _fileProviders)
        {
            var contents = provider.GetDirectoryContents(subpath);
            if (contents != null && contents.Exists)
            {
                return contents;
            }
        }

        return new NotFoundDirectoryContents();
    }

    public IFileInfo GetFileInfo(string subpath)
    {
        foreach (var provider in _fileProviders)
        {
            var fileInfo = provider.GetFileInfo(subpath);
            if (fileInfo != null && fileInfo.Exists)
            {
                return fileInfo;
            }
        }

        return new NotFoundFileInfo(subpath);
    }

    public IExpirationTrigger Watch(string filter)
    {
        foreach (var provider in _fileProviders)
        {
            var trigger = provider.Watch(filter);
            if (trigger != null)
            {
                return trigger;
            }
        }

        return NoopTrigger.Singleton;
    }
}

// copied from FileSystem repo

class NotFoundFileInfo : IFileInfo
{
    private readonly string _name;

    public NotFoundFileInfo(string name)
    {
        _name = name;
    }

    public bool Exists
    {
        get { return false; }
    }

    public bool IsDirectory
    {
        get { return false; }
    }

    public DateTimeOffset LastModified
    {
        get { return DateTimeOffset.MinValue; }
    }

    public long Length
    {
        get { return -1; }
    }

    public string Name
    {
        get { return _name; }
    }

    public string PhysicalPath
    {
        get { return null; }
    }

    public Stream CreateReadStream()
    {
        throw new FileNotFoundException(string.Format("The file {0} does not exist.", Name));
    }
}

class NotFoundDirectoryContents : IDirectoryContents
{
    public bool Exists
    {
        get { return false; }
    }

    public IEnumerator<IFileInfo> GetEnumerator()
    {
        return Enumerable.Empty<IFileInfo>().GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

class NoopTrigger : IExpirationTrigger
{
    public static NoopTrigger Singleton { get; } = new NoopTrigger();

    private NoopTrigger()
    {
    }

    public bool ActiveExpirationCallbacks
    {
        get { return false; }
    }

    public bool IsExpired
    {
        get { return false; }
    }

    public IDisposable RegisterExpirationCallback(Action<object> callback, object state)
    {
        throw new InvalidOperationException("Trigger does not support registering change notifications.");
    }
}
@kichalla
Copy link
Member Author

Ah, so looks like this is a dupe of #49

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

1 participant