ぷろじぇくと、みすじら。

ASP.NET CoreのJSON設定をファイル以外から読み込む

Created at:

大抵の場合ではASP.NETのConfigurationBuilderでAddJsonFileを呼んでファイルパスを指定してJSONファイルを読み込みますが、もしかすると物理的なファイルではなく例えばStringから読み込みたいといった場合があるかもしれません。

そんな時は IFileProvider を実装することで対応できます。

例えば、AddJsonFileに指定されたパスをJSONそのものとして扱ってしまえというようなものも作れて、以下のようなコードで実現できます。

// Install-Package Microsoft.Extensions.Configuration
// Install-Package Microsoft.Extensions.Configuration.Json
// Install-Package Microsoft.Extensions.FileProviders.Abstractions
void Main()
{
    var configuration = new ConfigurationBuilder()
        .AddJsonFile(new VirtualFileProvider(), @"{
            ""Foo"": ""barbaz"",
            ""Hoge"": 1234
        }", false, false)
        .Build();

    configuration.GetChildren().Dump();
}

public class VirtualFileProvider : IFileProvider
{
    public IDirectoryContents GetDirectoryContents(string subpath)
    {
        return new NotFoundDirectoryContents();
    }

    public IFileInfo GetFileInfo(string subpath)
    {
        return new VirtualFileInfo("virtual.json", Encoding.UTF8.GetBytes(subpath));
    }

    public IChangeToken Watch(string filter)
    {
        return NullChangeToken.Singleton;
    }
}

public class VirtualFileInfo : IFileInfo
{
    private byte[] _bytes;

    public VirtualFileInfo(string path, byte[] bytes)
    {
        _bytes = bytes;
        PhysicalPath = path;
    }

    public bool Exists => true;

    public long Length => _bytes.Length;

    public string PhysicalPath { get; }

    public string Name => Path.GetFileName(PhysicalPath);

    public DateTimeOffset LastModified => DateTime.Now;

    public bool IsDirectory => false;

    public Stream CreateReadStream()
    {
        return new MemoryStream(_bytes);
    }
}

要するにファイルを表す IFileInfo を返す、IFileProvider を実装して AddJsonFile メソッドに渡すことでその IFileProvider を通して内容を読み込むことになります。

上記の例では指定されたパスをそのままbyte配列にして IFileInfo で Stream として返すというだけのものです(重要ではないプロパティは適当なものを返す)。

テストやちょっと試したいときなどにファイルを作れない/作りたくないといった場合、他のデータソースから取得するといったパターンが必要になったときには役立つかもしれません。