我有一个 .NET Core 工作应用程序,想添加一个自定义文件记录器,因为Microsoft.Extensions.Logging没有提供这个。我不想为此使用额外的包(例如 Serilog)。
我将有关日志目录和日志文件的信息放入我的选项类中。这个选项类还有一个实现IValidateOptions接口的验证器。如果发生错误,此验证器会注入一个记录器实例以记录验证错误。
文件记录器提供程序需要注入选项监视器才能访问目录和文件配置。
运行应用程序时,我不幸收到异常
System.AggregateException: '某些服务无法构建'
与内容
验证服务描述符“ServiceType: Microsoft.Extensions.Hosting.IHostApplicationLifetime Lifetime: Singleton ImplementationType: Microsoft.Extensions.Hosting.Internal.ApplicationLifetime”时出错:检测到“Microsoft.Extensions.Logging.ILoggerFactory”类型的服务存在循环依赖'。Microsoft.Extensions.Hosting.IHostApplicationLifetime(Microsoft.Extensions.Hosting.Internal.ApplicationLifetime) -> Microsoft.Extensions.Logging.ILogger<Microsoft.Extensions.Hosting.Internal.ApplicationLifetime>(Microsoft.Extensions.Logging.Logger<Microsoft.Extensions .Hosting.Internal.ApplicationLifetime>) -> Microsoft.Extensions.Logging.ILoggerFactory(Microsoft.Extensions.Logging.LoggerFactory) -> System.Collections.Generic.IEnumerable<Microsoft.Extensions.Logging.ILoggerProvider> ->
这是有道理的,因为当注入一个新的记录器实例时,这个实例被注入了选项。这些将触发注入新记录器实例的验证器。所以它又开始了。
记录器 => 选项 => 验证器 => 记录器 => 选项 => 验证器 => 记录器 => 选项 => 验证器 => ...
我不知道如何解决这个问题,因为我的文件记录器需要访问配置选项,而我的选项验证器应该记录验证错误。
有任何想法吗?
如果您想获得有关该应用程序的概述,这就是我为重现它所做的:
<FrameworkReference Include="Microsoft.AspNetCore.App" />到第一个项目组以访问 Kestrel 和 Web 内容MyLib在项目中添加一个库并在主项目中引用它.
public class MyOptions
{
public string DirectoryPath …Run Code Online (Sandbox Code Playgroud) 我有一个类型的字典
Dictionary<int, (float, float)>
Run Code Online (Sandbox Code Playgroud)
尝试从中读取值时,我无法使用这种方式
if (myDict.TryGetValue(1, out (float tupleItem1, float tupleItem2))) { /* ... */ }
Run Code Online (Sandbox Code Playgroud)
因为那样我会收到编译错误
它的工作方式是
if (myDict.TryGetValue(1, out (float, float) theTuple)) { /* ... */ }
Run Code Online (Sandbox Code Playgroud)
有没有办法可以像这样直接初始化变量?
if (!myDict.TryGetValue(1, out (float tupleItem1, float tupleItem2)))
{
/* handle if not found */
tupleItem1 = 111;
tupleItem2 = -12345;
}
Run Code Online (Sandbox Code Playgroud) 我有一个 .Net 5 解决方案并使用代码样式分析构建项目。每个违反规则都会导致警告。但是构建命令以代码 0 退出。
我创建了一个.gitlab-ci.yml文件,如果抛出任何构建警告,该文件应该将管道标记为不稳定。
image: mcr.microsoft.com/dotnet/sdk:5.0
stages:
- build
- unit-tests
build:
stage: build
script:
- |-
dotnet build --output build -consoleloggerparameters:"Summary;Verbosity=normal" -m -p:"WarnLevel=5;EnforceCodeStyleInBuild=true" -t:"clean,build" -fl1 "/flp1:warningsonly";
if ((!$LASTEXITCODE) -and (Get-Content "msbuild1.log"))
{
# >>> mark stage as unstable here <<<
}
artifacts:
paths:
- build
unit-tests:
stage: unit-tests
script:
- dotnet test --no-build --output build
dependencies:
- build
Run Code Online (Sandbox Code Playgroud)
阶段本身通过了,但我希望它以不稳定的状态通过(因为警告),不幸的是它是绿色的。
一个糟糕的解决方案是-warnaserror为构建命令添加标志并allow_failure: true用于舞台。这将使阶段进入不稳定状态,但由于缺少构建,下一阶段将失败。
那么检查构建命令是否以警告结束将阶段标记为不稳定的正确方法是什么?
我有一个 .NET Core worker 项目,想添加一个提供多个 HTTP 端点的库。我必须留在工作人员项目中,我无法将其更改为 Web API 项目。到目前为止我做了什么:
<FrameworkReference Include="Microsoft.AspNetCore.App" />到项目组以访问 webbuilder 的东西.
public static class IApplicationBuilderExtensions
{
public static IApplicationBuilder AddLibrary(this IApplicationBuilder applicationBuilder)
{
applicationBuilder.UseRouting();
applicationBuilder.UseEndpoints(endpoints => { endpoints.MapControllers(); });
return applicationBuilder;
}
}
public static class IServiceCollectionExtensions
{
public static IServiceCollection AddLibrary(this IServiceCollection services)
{
services.AddMvc(); // this might be not needed
services.AddControllers();
return services; …Run Code Online (Sandbox Code Playgroud) 鉴于具有多个 xUnit 测试项目的 .Net 5 解决方案,我可以dotnet test从解决方案的根目录运行,它将运行所有测试。
我想根据我运行的https://docs.microsoft.com/en-us/dotnet/core/testing/unit-testing-code-coverage?tabs=windows#integrate-with-net-test生成报告dotnet test --collect:"XPlat Code Coverage"它为每个测试项目生成一个coverage.cobertura 文件。
基于https://docs.microsoft.com/en-us/dotnet/core/testing/unit-testing-code-coverage?tabs=windows#generate-reports我知道我可以安装该dotnet-reportgenerator-globaltool工具并获得可视化的 HTML基于每个coverage.cobertura 文件的报告。
但是我想添加一个 CI 管道,当线路覆盖率低于 x % 时,我想让管道失败。
鉴于以下示例 Gitlab CI 配置
image: mcr.microsoft.com/dotnet/sdk:5.0
stages:
- tests
tests:
stage: tests
script:
- dotnet test --collect:"XPlat Code Coverage"
Run Code Online (Sandbox Code Playgroud)
coverage.cobertura.xml如果值低于例如 80%,我如何收集所有生成的文件,读取行覆盖率并让管道失败?
例子:
tests:
stage: tests
script:
- dotnet test --collect:"XPlat Code Coverage"
# for each coverage.cobertura file found in the test projects
# parse the file
# …Run Code Online (Sandbox Code Playgroud) 我想使用 Kestrel 和 System.IO.Pipelines 包创建一个 TCP 侦听器。我收到的消息将始终是HL7 消息。一个示例消息可能是
MSH|^~&|MegaReg|XYZHospC|SuperOE|XYZImgCtr|20060529090131-0500||ADT^A01^ADT_A01|01052901|P|2.5 EVN|||200605290901|2UA5^820909|4UA|20909|2UA|5 ||KLEINSAMPLE^BARRY^Q^JR||19620910|M||2028-9^^HL70005^RA99113^^XYZ|260 GOODWIN CREST Drive^^BIRMINGHAM^AL^35209^^M~NICKELL'S PICKLESAVE00TH1000W^100 ^伯明翰^AL^35200^^O||||||0105I30001^^^99DEF^AN PV1||I|W^389^1^UABH^^^^3||||12345^摩根^REX^ J^^^MD^0010^UAMC^L||67890^GRAINGER^LUCY^X^^^MD^0010^UAMC^L|MED|||||A0||13579^POTTER^SHERMAN^T^^^ MD^0010^UAMC^L||||||||||||||||||||||||200605290900 OBX|1|NM|^体高||1.80|m^米^ISO+|||||F OBX|2|NM|^体重||79|kg^公斤^ISO+|||||F AL1|1||^阿司匹林DG1|1||786.50^胸痛,未指定^I9|||A
唯一需要注意的重要事项是每个传入的 HL7 消息都以垂直制表符开头,因此您知道消息的开始位置。每个 HL7 消息都包含多个段,所以我想我必须遍历每个段。处理请求后,我想发回 HL7 消息作为响应。首先我想出了这个
internal class HL7Listener : ConnectionHandler
{
public override async Task OnConnectedAsync(ConnectionContext connection)
{
IDuplexPipe pipe = connection.Transport;
await FillPipe(pipe.Output);
await ReadPipe(pipe.Input);
}
private async Task FillPipe(PipeWriter pipeWriter)
{
const int minimumBufferSize = 512;
while (true)
{
Memory<byte> memory = pipeWriter.GetMemory(minimumBufferSize);
try
{
int bytesRead = 32; // not sure …Run Code Online (Sandbox Code Playgroud) 这就是我使用 Github 的方式:
jobs:
run-tests:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./MyApp
steps:
- uses: actions/checkout@v2
- name: Setup .NET
uses: actions/setup-dotnet@v1
with:
dotnet-version: 5.0.x
- name: Restore dependencies
run: dotnet restore
- name: Build project
run: dotnet build --no-restore
- name: Run tests
run: dotnet test --no-build
Run Code Online (Sandbox Code Playgroud)
这次在 Gitlab 上,我的项目解决方案文件位于存储库的根目录中。我创建了一个.gitlab-ci.yml文件并从
image: mcr.microsoft.com/dotnet/sdk:5.0
stages:
- restore-dependencies
- build-solution
- run-tests
restore-dependencies:
stage: restore-dependencies
script:
- dotnet restore --packages packages
artifacts:
paths:
- packages
build-solution:
stage: build-solution
script:
- dotnet …Run Code Online (Sandbox Code Playgroud) 我想根据本教程为我的 C# 项目生成单个覆盖率报告
https://docs.microsoft.com/en-us/dotnet/core/testing/unit-testing-code-coverage
使用以下配置启动 Gitlab CI 管道时
image: mcr.microsoft.com/dotnet/sdk:5.0
stages:
- build
- unit-tests
build:
stage: build
script:
- dotnet build --output build
artifacts:
paths:
- build
unit-tests:
stage: unit-tests
script:
- |-
dotnet test --no-build --output build --collect:"XPlat Code Coverage";
dotnet tool install -g dotnet-reportgenerator-globaltool;
reportgenerator -reports:'**/coverage.cobertura.xml' -targetdir:'CoverageReports' -reporttypes:'Cobertura';
artifacts:
reports:
cobertura: CoverageReports/Cobertura.xml
dependencies:
- build
Run Code Online (Sandbox Code Playgroud)
我收到以下错误
报告文件模式“**/coverage.cobertura.xml”无效。没有找到匹配的文件。
ls在运行 reportgenerator 命令之前使用检查目录时,我可以看到没有匹配的文件(尽管它们应该存在)。
我希望每个测试项目有一个coverage.cobertura.xml 文件,例如
...\myRepo\xUnitTestProject1\TestResults\380e65f7-48d5-468f-9cbc-550c8e0aeda8\coverage.cobertura.xml...\myRepo\xUnitTestProject2\TestResults\c96c55f7-40d3-483e-a136-573615e3a9c3\coverage.cobertura.xml我目前的解决方案:
看来我必须再次运行构建。所以我替换了这条线
dotnet test --no-build --output build --collect:"XPlat Code Coverage";
和
dotnet …
我想创建一个 .NET Core 工作服务,它在后台作为 Windows 服务运行,并且能够通过 TCP 接收特定消息和通过 HTTP 接收特定消息。我熟悉创建 .NET Core Web API,但现在我无法使用 Web API 模板。SO上的一些帖子告诉我创建一个Web API项目并向其中添加工作服务和TCP服务器,例如
在 .Net Core Worker Service 中托管 Web API - 无法引用 IWebHostEnvironment
但由于这个项目是一个侦听 TCP 消息和 HTTP 请求的服务,我更愿意保留工作服务模板并为其添加一个 TCP 服务器和 HTTP 侦听器。我唯一遇到的困难是在不使用模板的情况下在该工作服务中创建 Web API。我认为这可以通过配置 Kestrel 服务器来解决
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?view=aspnetcore-3.1
但是 Service Worker 项目不是 Web 应用程序,因此它无法访问该ConfigureWebHostDefaults方法,请在此处获取更多信息
IHostBuilder 不包含 ConfigureWebHostDefaults 的定义
那么是否有可能创建一个在启动时启动 TCP 服务器(这没问题)和侦听 REST API(不使用 Web API 模板)的工作服务项目?或者我是否总是必须首先创建一个 Web API 并尝试使其行为像一个工作服务并在其启动时的某处添加一个 TCP 服务器?
我有一个byte[]代表消息中的分隔符列表。我收到 aReadOnlySequence<byte>作为参数,并且知道我可以使用它buffer.PositionOf来查找分隔符的第一次出现。但是我必须在那次发生之后找到位置。
byte[] delimiters = { 0x1c, 0x0d };
byte firstDelimiter = delimiters.First();
SequencePosition? positionOfFirstDelimiter = buffer.PositionOf(firstDelimiter);
if (positionOfFirstDelimiter != null)
{
/*
How to move positionOfFirstDelimiter by delimiters?
positionOfFirstDelimiter.Value + delimiters.Length
does not work
*/
SequencePosition positionAfterDelimiters = /* ??? */;
}
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?