小编Ola*_*son的帖子

使用依赖于记录器的选项验证器创建依赖于选项的自定义记录器时出现循环依赖异常

我有一个 .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> ->

这是有道理的,因为当注入一个新的记录器实例时,这个实例被注入了选项。这些将触发注入新记录器实例的验证器。所以它又开始了。

记录器 => 选项 => 验证器 => 记录器 => 选项 => 验证器 => 记录器 => 选项 => 验证器 => ...

我不知道如何解决这个问题,因为我的文件记录器需要访问配置选项,而我的选项验证器应该记录验证错误。

有任何想法吗?


如果您想获得有关该应用程序的概述,这就是我为重现它所做的:

  • 创建一个新的 .NET Core Worker 项目
  • 转到 .csproj 文件并添加<FrameworkReference Include="Microsoft.AspNetCore.App" />到第一个项目组以访问 Kestrel 和 Web 内容
  • MyLib在项目中添加一个库并在主项目中引用它
  • 在库中,我创建了一个选项类,其中包含文件记录器的信息

.

public class MyOptions
{
    public string DirectoryPath …
Run Code Online (Sandbox Code Playgroud)

c# .net-core

11
推荐指数
1
解决办法
569
查看次数

如果值是元组,如何通过 .TryGetValue() 从字典中读取值?

我有一个类型的字典

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)

c#

11
推荐指数
1
解决办法
590
查看次数

如果 Powershell 条件结果为真,如何将阶段标记为不稳定?

我有一个 .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 c# powershell continuous-integration gitlab-ci

10
推荐指数
1
解决办法
150
查看次数

从类库注册 Web API 控制器

我有一个 .NET Core worker 项目,想添加一个提供多个 HTTP 端点的库。我必须留在工作人员项目中,我无法将其更改为 Web API 项目。到目前为止我做了什么:

  • 我创建了一个工人项目
  • 我创建了一个库项目
  • 我在 worker 项目中添加了对库的引用
  • Worker.csprojLib.csproj 中,我添加<FrameworkReference Include="Microsoft.AspNetCore.App" />到项目组以访问 webbuilder 的东西
  • 我在库项目中安装了包Microsoft.AspNetCore.Mvc.Core
  • 在库项目中,我添加了几个扩展类和一个 Web API 控制器用于测试目的

.

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)

c# kestrel asp.net-core-mvc .net-core

9
推荐指数
1
解决办法
2035
查看次数

如何获取和解析 CI 管道中所有生成的coverage.cobertura 文件?

鉴于具有多个 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)

c# code-coverage xunit gitlab-ci

9
推荐指数
2
解决办法
317
查看次数

如何使用 System.IO.Pipelines 包创建响应 TCP 侦听器?

我想使用 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)

c# kestrel .net-core system.io.pipelines

8
推荐指数
1
解决办法
582
查看次数

如何为 C# 项目设置 Gitlab CI 作业工件?

这就是我使用 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)

.net c# gitlab gitlab-ci gitlab-ci-runner

7
推荐指数
2
解决办法
297
查看次数

在 Gitlab CI 管道内运行时,dotnet-reportgenerator 无法找到任何coverage.cobertura.xml

我想根据本教程为我的 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 …

c# continuous-integration gitlab-ci gitlab-ci-runner

7
推荐指数
1
解决办法
208
查看次数

创建 .NET Core 辅助服务,侦听 TCP 消息和 HTTP 请求

我想创建一个 .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 服务器?

c# .net-core

6
推荐指数
0
解决办法
1690
查看次数

如何通过添加一堆字节在缓冲区中“向右”移动 SequencePosition?

我有一个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)

有任何想法吗?

c# .net-core

6
推荐指数
0
解决办法
53
查看次数