Dan*_*ani 3 c# appsettings asp.net-core asp.net-core-1.0
我有一个应用程序拆分为两个项目:一个 Web 应用程序和一个类库。仅Startup在网络应用程序中:
var builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
Run Code Online (Sandbox Code Playgroud)
我希望将 appsettings.json 放在该类库中并从那里加载。那可能吗?我怎样才能做到这一点?
我发现的最佳解决方案需要创建新的 IFileProvider 和 IFileInfo,然后将 JSON 设置文件嵌入到程序集中。
该解决方案重用现有的 AddJsonFile 逻辑。这样你只需要告诉配置系统如何以及在哪里找到 JSON 文件,而不是如何解析它。
该解决方案与.NET Core 1.0兼容。
用法:
public class Startup
{
private readonly AppSettings _appSettings;
public Startup(IHostingEnvironment env)
{
Assembly assembly = GetType().GetTypeInfo().Assembly;
new ConfigurationBuilder()
.AddEmbeddedJsonFile(assembly, "appsettings.json")
.AddEmbeddedJsonFile(assembly, $"appsettings.{env.EnvironmentName.ToLower()}.json")
.Build();
}
...
}
Run Code Online (Sandbox Code Playgroud)
通过更新类库的 project.json 来嵌入文件:
...
"buildOptions": {
"embed": [
"appsettings.json",
"appsettings.development.json",
"appsettings.production.json"
]
}
...
Run Code Online (Sandbox Code Playgroud)
IEmbeddedFileInfo 实现:
public class EmbeddedFileInfo : IFileInfo
{
private readonly Stream _fileStream;
public EmbeddedFileInfo(string name, Stream fileStream)
{
if (name == null) throw new ArgumentNullException(nameof(name));
if (fileStream == null) throw new ArgumentNullException(nameof(fileStream));
_fileStream = fileStream;
Exists = true;
IsDirectory = false;
Length = fileStream.Length;
Name = name;
PhysicalPath = name;
LastModified = DateTimeOffset.Now;
}
public Stream CreateReadStream()
{
return _fileStream;
}
public bool Exists { get; }
public bool IsDirectory { get; }
public long Length { get; }
public string Name { get; }
public string PhysicalPath { get; }
public DateTimeOffset LastModified { get; }
}
Run Code Online (Sandbox Code Playgroud)
IFileInfo 实现:
public class EmbeddedFileProvider : IFileProvider
{
private readonly Assembly _assembly;
public EmbeddedFileProvider(Assembly assembly)
{
if (assembly == null) throw new ArgumentNullException(nameof(assembly));
_assembly = assembly;
}
public IFileInfo GetFileInfo(string subpath)
{
string fullFileName = $"{_assembly.GetName().Name}.{subpath}";
bool isFileEmbedded = _assembly.GetManifestResourceNames().Contains(fullFileName);
return isFileEmbedded
? new EmbeddedFileInfo(subpath, _assembly.GetManifestResourceStream(fullFileName))
: (IFileInfo) new NotFoundFileInfo(subpath);
}
public IDirectoryContents GetDirectoryContents(string subpath)
{
throw new NotImplementedException();
}
public IChangeToken Watch(string filter)
{
throw new NotImplementedException();
}
}
Run Code Online (Sandbox Code Playgroud)
创建易于使用的 AddEmbeddedJsonFile 扩展方法。
public static class ConfigurationBuilderExtensions
{
public static IConfigurationBuilder AddEmbeddedJsonFile(this IConfigurationBuilder cb,
Assembly assembly, string name, bool optional = false)
{
// reload on change is not supported, always pass in false
return cb.AddJsonFile(new EmbeddedFileProvider(assembly), name, optional, false);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5186 次 |
| 最近记录: |