我有一个无状态服务项目(.sfproj)和相应的控制台应用程序项目的解决方案。
我已将appsettings.json添加到控制台应用程序项目中,并试图使用此设置访问权限:
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
//return this.CreateServiceRemotingInstanceListeners(); //This line works
return new ServiceInstanceListener[] //This line causes an error in Service Fabric Explorer
{
new ServiceInstanceListener(serviceContext =>
new KestrelCommunicationListener(serviceContext, "ServiceEndpoint", (url, listener) =>
{
ServiceEventSource.Current.ServiceMessage(serviceContext, $"Starting Kestrel on {url}");
return new WebHostBuilder()
.UseKestrel()
.ConfigureAppConfiguration((builderContext, config) =>
{
config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
})
.ConfigureServices(
services => services
.AddSingleton<StatelessServiceContext>(serviceContext))
.UseContentRoot(Directory.GetCurrentDirectory())
//.UseStartup<Startup>() //Startup.cs does not exist
.UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
.UseUrls(url)
.Build();
}))
};
}
这不会编译,因为我没有Startup
类,因为它不是Web api项目,它使用的是无状态服务。我在控制台应用程序中仅有的类是Program.cs
,Service.cs
和ServiceEventSource.cs
我尝试删除.UseStartup<Startup>()
使其进行编译,但是,当我运行该应用程序时,在Service Fabric Explorer中出现以下错误:
'System.FM' reported Error for property 'State'.
Partition is below target replica or instance count.
fabric:/Integration/Integration.Service 1 1 9810816d-5be9-4b53-9eed-c5be403219b0
InBuild _Node_1 132003711574580709
(Showing 1 out of 1 instances. Total available instances: 0)
我可以改用return this.CreateServiceRemotingInstanceListeners();
来解决此问题,但是我不知道如何设置对appsettings.json的访问。
如何从无状态服务中访问appsettings.json
?
编辑:
我设法在Service.cs
中使用它来工作:
protected override async Task RunAsync(CancellationToken cancellationToken)
{
Microsoft.AspNetCore.WebHost.CreateDefaultBuilder()
.ConfigureAppConfiguration((builderContext, config) =>
{
var env = builderContext.HostingEnvironment;
config.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
})
.UseStartup<Startup>()
.Build()
.Run();
}
我将其添加到ServiceManifest.xml
中,以确保env.ContentRootPath
指向包含appsettings.json
文件的代码包文件夹(默认似乎是Work文件夹,对我来说是空的) :
<EntryPoint>
<ExeHost>
<Program>TheAppNameGoesHere.exe</Program>
<WorkingFolder>CodePackage</WorkingFolder>
</ExeHost>
</EntryPoint>
我添加了此Startup
类:
public class Startup
{
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{ }
}
我觉得必须有一种更好的访问appsettings.json
的方法,尤其是考虑到Startup.Configure()
方法无济于事。
有人知道更好的访问appsettings.json
的方法吗?
答案 0 :(得分:0)
发生这种情况是因为您必须指定运行该应用程序入口点的程序集的名称。 docs解释了如何设置。
当您使用.UseStartup<Startup>()
时,它会从Startup
类获取程序集信息,因为您没有该信息,所以它不知道入口点在哪里。
This github issue和this显示类似的问题。
这是我从一个在SF中运行的应用中得到的示例:
var builder = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.ConfigureServices(services => services.AddSingleton(startup))
.UseApplicationInsights()
.UseSetting(WebHostDefaults.ApplicationKey, startup.GetType().Assembly.FullName);
在上面的示例中,startup
是使用以下方法实现Microsoft.AspNetCore.Hosting.IStartup
的类的实例:
void Configure(IApplicationBuilder app);
IServiceProvider ConfigureServices(IServiceCollection services);
PS:您在上面的示例中不使用.UseStartup<Startup>()
,但是如果项目中有一个,则可以使用。