728x90
반응형

반복적인 using 처리를 하나의 파일에 global using 으로 정의해 주면 같은 프로젝트의 모든 파일들은 using 을 하지 않아도 된다.

기존

using System.Diagnostics;

namespace Test;

public class TestA
{
    public TestA()
    {
        Debug.Write("A");
    }
}
using System.Diagnostics;

namespace Test;

public class TestB
{
    public TestB()
    {
        Debug.Write("B");
    }
}


파일 2개에 using System.Diagnostics; 이 되어있는데 이를 GlobalUsings.cs 파일을 하나 추가하여 아래와 같이 해주면

global using System.Diagnostics;

프로젝트에 속한 모든 파일에 using 을 하지 않아도 using 이 된것처럼 사용이 가능하다

결과

namespace Test;

public class TestA
{
    public TestA()
    {
        Debug.Write("A");
    }
}
namespace Test;

public class TestB
{
    public TestB()
    {
        Debug.Write("B");
    }
}
반응형
728x90
반응형

.NET 6.0 으로 프로젝트를 구성하면

string 에도 ? 를 붙이라는 에러가 나타난다.

이를 무시하고 싶을때 아래처럼 프로젝트 속성의 빌드>일반 탭에서 'Null 허용' 을 사용안함으로 처리하면된다.

반응형
728x90
반응형

> Serilog 적용하기

1. 콘솔 프로젝트 생성(.NET 6.0)

2. Nuget 설치
   Serilog.Sinks.Console
   Serilog.Sinks.File

3. Log 설정

using Serilog;
using Serilog.Core;

namespace SerilogTest;

class Program
{
    static void Main(string[] args)
    {
        var levelSwitch = new LoggingLevelSwitch();

        Log.Logger = new LoggerConfiguration()
                    // 최소 지정 로그 레벨 : Info 레벨 이상 로그를 기록한다는 의미
                    .MinimumLevel.Information()
                    // 콘솔에도 내용을 남김
                    .WriteTo.Console()
                    //파일로 기록할 로그 파일명을 입력
                    .WriteTo.File(@"c:\log\log.txt", rollingInterval: RollingInterval.Day, rollOnFileSizeLimit: true)
                    .CreateLogger();

        for (int idx = 0; idx < 100; idx++)
        {
            Log.Information($"{idx} - Serilog Test");
        }

        Log.CloseAndFlush();
    }
}

4. 결과


> Seq 연동하기

1. Seq 설치
https://datalust.co/download

 

Seq — centralized structured logs for .NET, Java, Node.js

Seq is the intelligent search, analysis, and alerting server built specifically for modern structured log data.

datalust.co

2.  설치 후 관리자 설정

Browse Seq 버튼을 클릭하면 웹이사이트가 열리고 아까 지정한 아이디와 비밀번호를 입력한다.

3. Seq 설정을 끝났고 프로젝트에 Nuget 설치
  Serilog.Sinks.Seq

4. Serilog 를 이용해 Seq 연동
.WriteTo.Seq("http://localhost:5341") 코드를 추가하면된다.

using Serilog;
using Serilog.Core;

namespace SerilogTest;

class Program
{
    static void Main(string[] args)
    {
        var levelSwitch = new LoggingLevelSwitch();

        Log.Logger = new LoggerConfiguration()
                    // 최소 지정 로그 레벨 : Info 레벨 이상 로그를 기록한다는 의미
                    .MinimumLevel.Information()
                    // 콘솔에도 내용을 남김
                    .WriteTo.Console()
                    //파일로 기록할 로그 파일명을 입력
                    .WriteTo.File(@"c:\log\log.txt", rollingInterval: RollingInterval.Day, rollOnFileSizeLimit: true)
                    // Seq 에 로그 정보 입력
                    .WriteTo.Seq("http://localhost:5341", controlLevelSwitch: levelSwitch)
                    .CreateLogger();

        for (int idx = 0; idx < 100; idx++)
        {
            Log.Information($"{idx} - Serilog Test");
        }

        Log.CloseAndFlush();
    }
}

프로그램을 실행하고 웹사이트를 리프레쉬하면 아래처럼 로그 내용이 보여지게된다.

 

소스

https://github.com/kei-soft/KJunBlog/tree/master/SerilogTest

 

GitHub - kei-soft/KJunBlog

Contribute to kei-soft/KJunBlog development by creating an account on GitHub.

github.com

 

반응형
728x90
반응형

Visual Studio 에서 데이터 확인을 위해 Cosole.WriteLine 로 데이터를 표시했는데 출력창에 나타나지 않았다

2019 버전에서는 이상없이 출력이 되었다

확인해 보니 2022 부터는 using System.Diagnostics; 을 하고 Debug.WriteLine 을 써야 출력창에 표시가 된다.

반응형
728x90
반응형

아래 링크에서 파일을 다운받아서 설치한다.
https://marketplace.visualstudio.com/items?itemName=SharpDevelopTeam.ILSpy

실행하여 설치된 Visual Studio 를 선택 (2022 는 없다 ㅜㅠ)

설치가 끝나면 프로젝트를 열어 참조 중 하나를 우클릭하면 'Open in ILSpay' 메뉴가 보이고 이를 클릭하면 

아래처럼 디컴파일된 소스가 보이게 된다.

반응형
728x90
반응형

MessageBox 를 이용해 메세지를 띄울때 그전에 띄워진 TopMost가 true인 창으로 인해 가려지는 경우가 있다.
가려지는 걸 막기 위해서는 MessageBox 를 띄울때 TopMost 를 true 로 처리해서 띄워야 하는데 이를 처리하는 방법은 아래와같다.

1.

using System.Windows;
MessageBox.Show("message.", "title", MessageBoxButton.OK, MessageBoxImage.Exclamation, MessageBoxResult.OK, MessageBoxOptions.DefaultDesktopOnly);

MessageBoxOptions.DefaultDesktopOnly 항목이 TopMost=true 로 처리되게 해준다

2.

 System.Windows.Forms.MessageBox.Show(new System.Windows.Forms.Form { TopMost = true }, "message", "title");

 

반응형
728x90
반응형

Server 구성

1. ASP.NET Core gRPC 서비스 프로젝트 생성


2. proto 파일 정의 (weather.proto)

syntax = "proto3";

import "google/protobuf/empty.proto";
import "google/protobuf/timestamp.proto";

option csharp_namespace = "GrpcStreamServer";

package WeatherForecast;

// The weather service definition.
service WeatherForecasts {
  // Sends a weatherStream
 rpc GetWeatherStream (google.protobuf.Empty) returns (stream WeatherData);
}

message WeatherData {
  google.protobuf.Timestamp dateTimeStamp = 1;
  int32 temperatureC = 2;
  int32 temperatureF = 3;
  string summary = 4;
}


3. WeatherService.cs 에 동작 정의
(날짜별 온도값을 랜덤하게 반환한다.)

using Google.Protobuf.WellKnownTypes;

using Grpc.Core;

using GrpcStreamServer;

using static GrpcStreamServer.WeatherForecasts;

namespace GrpcStreamServer.Services
{
    public class WeatherService : WeatherForecastsBase
    {
        private readonly ILogger<WeatherService> _logger;

        public WeatherService(ILogger<WeatherService> logger) => _logger = logger;

        public override async Task GetWeatherStream(Empty _, IServerStreamWriter<WeatherData> responseStream, ServerCallContext context)
        {
            var rng = new Random();
            var now = DateTime.UtcNow;

            var i = 0;
            while (!context.CancellationToken.IsCancellationRequested && i < 20)
            {
                await Task.Delay(500); // Gotta look busy

                var forecast = new WeatherData
                {
                    DateTimeStamp = Timestamp.FromDateTime(now.AddDays(i++)),
                    TemperatureC = rng.Next(-20, 55),
                    Summary = ""//Summaries[rng.Next(Summaries.Length)]
                };

                _logger.LogInformation("Sending WeatherData response");

                await responseStream.WriteAsync(forecast);
            }
        }
    }
}


4. Program.cs 에서 WeatherService Mapping

using GrpcStreamServer.Services;

var builder = WebApplication.CreateBuilder(args);

// Additional configuration is required to successfully run gRPC on macOS.
// For instructions on how to configure Kestrel and gRPC clients on macOS, visit https://go.microsoft.com/fwlink/?linkid=2099682

// Add services to the container.
builder.Services.AddGrpc();

var app = builder.Build();

app.UseRouting();

app.UseEndpoints(endpoints =>
{
    endpoints.MapGrpcService<WeatherService>();
});

// Configure the HTTP request pipeline.
//app.MapGrpcService<WeatherService>();

app.Run();


5. Properties 의 launchSettings.json 파일에 서비스 주소 정의 및 기타 옵션 설정

{
  "profiles": {
    "GrpcStreamServer": {
      "commandName": "Project",
      "dotnetRunMessages": true,
      "launchBrowser": false,
      "applicationUrl": "http://localhost:5038;https://localhost:7038",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}


6. appsettings.json 파일에서 Protocols 정의 및 Log Level 지정

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "Kestrel": {
    "EndpointDefaults": {
      "Protocols": "Http2"
    }
  }
}


7. appsettings.Development.json 파일에서 Develope 모드 일때 Info 도 로그가 찍히도록 Log Level 정의

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning",
      "Microsoft.AspNetCore.Hosting": "Information",
      "Microsoft.AspNetCore.Routing.EndpointMiddleware": "Information"
    }
  }
}


8. Server 실행


Client 구성

1. 콘솔앱 프로젝트 생성


2. Server 에서 만들어진 proto 파일을 동일하게 Protos 폴더를 만들어 복사한다.


3. Nuget 설치
Google.Protobuf
Grpc.Net.Client
Grpc.Tools


4. 프로젝트파일 편집
<Protobuf Include="Protos\weather.proto" GrpcServices="Server" />
Server 를 Client 로 아래 처럼 바꾼다.
<Protobuf Include="Protos\weather.proto" GrpcServices="Client" />

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <None Remove="Protos\weather.proto" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Google.Protobuf" Version="3.20.1" />
    <PackageReference Include="Grpc.Net.Client" Version="2.45.0" />
    <PackageReference Include="Grpc.Tools" Version="2.45.0">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
  </ItemGroup>

  <ItemGroup>
    <Protobuf Include="Protos\weather.proto" GrpcServices="Client" />
  </ItemGroup>

</Project>


4.  빌드/다시빌드
빌드 하게되면 proto 파일을 이용해 c# 코드가 생성된다. (솔루션 탐색기에서 표시되지 않음)


5. 서버 연결 및 통신 (

using Google.Protobuf.WellKnownTypes;

using Grpc.Core;
using Grpc.Net.Client;

using GrpcStreamClient;

using var channel = GrpcChannel.ForAddress("http://localhost:5038");

var client = new WeatherForecasts.WeatherForecastsClient(channel);

var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
using var streamingCall = client.GetWeatherStream(new Empty(), cancellationToken: cts.Token);

try
{
    await foreach (var weatherData in streamingCall.ResponseStream.ReadAllAsync(cancellationToken: cts.Token))
    {
        Console.WriteLine($"{weatherData.DateTimeStamp.ToDateTime():s} | {weatherData.Summary} | {weatherData.TemperatureC} C");
    }
}
catch (RpcException ex) when (ex.StatusCode == StatusCode.Cancelled)
{
    Console.WriteLine("Stream cancelled.");
}

https 로 연결하면 SSL 인증서를 요구한다.
GetWeatherStream 을 호출하면 서버에서 데이터를 실시간으로 전달해준다.
CancellationTokenSource 로 5초 지나면 호출을 Cancel 한다.

아래는 서버와 클라이언트간에 테스트 결과




소스 : https://github.com/kei-soft/GrpcSample

 

반응형
728x90
반응형

Server 구성

1. ASP.NET Core gRPC 서비스 프로젝트 생성


2. proto 파일 정의

syntax = "proto3";

option csharp_namespace = "GrpcServer";

package greet;

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply);
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings.
message HelloReply {
  string message = 1;
}


3. GreeterService.cs 에 동작 정의

using Grpc.Core;

using GrpcServer;

namespace GrpcServer.Services
{
    public class GreeterService : Greeter.GreeterBase
    {
        private readonly ILogger<GreeterService> _logger;
        public GreeterService(ILogger<GreeterService> logger)
        {
            _logger = logger;
        }

        public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
        {
            return Task.FromResult(new HelloReply
            {
                Message = "Hello " + request.Name
            });
        }
    }
}


4. Program.cs 에서 GreeterService Mapping

using GrpcServer.Services;

var builder = WebApplication.CreateBuilder(args);

// Additional configuration is required to successfully run gRPC on macOS.
// For instructions on how to configure Kestrel and gRPC clients on macOS, visit https://go.microsoft.com/fwlink/?linkid=2099682

// Add services to the container.
builder.Services.AddGrpc();

var app = builder.Build();

// Configure the HTTP request pipeline.
app.MapGrpcService<GreeterService>();
app.MapGet("/", () => "Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");

app.Run();


5. Properties 의 launchSettings.json 파일에 서비스 주소 정의 및 기타 옵션 설정

{
  "profiles": {
    "GrpcServer": {
      "commandName": "Project",
      "dotnetRunMessages": true,
      "launchBrowser": false,
      "applicationUrl": "http://localhost:5253;https://localhost:7253",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}


6. appsettings.json 파일에서 Protocols 정의 및 Log Level 지정

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "Kestrel": {
    "EndpointDefaults": {
      "Protocols": "Http2"
    }
  }
}


7. appsettings.Development.json 파일에서 Develope 모드 일때 Info 도 로그가 찍히도록 Log Level 정의

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning",
      "Microsoft.AspNetCore.Hosting": "Information",
      "Microsoft.AspNetCore.Routing.EndpointMiddleware": "Information"
    }
  }
}


8. Server 실행

web page 확인

 

Client 구성

1. 콘솔앱 프로젝트 생성

2. Server 에서 만들어진 proto 파일을 동일하게 Protos 폴더를 만들어 복사한다.

3. Nuget 설치
Google.Protobuf
Grpc.Net.Client
Grpc.Tools

4. 프로젝트파일 편집
<Protobuf Include="Protos\greet.proto" GrpcServices="Server" /> 부분을 Client 로 아래 처럼 바꾼다.
<Protobuf Include="Protos\greet.proto" GrpcServices="Client" /> 

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <None Remove="Protos\greet.proto" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Google.Protobuf" Version="3.20.1" />
    <PackageReference Include="Grpc.Net.Client" Version="2.45.0" />
    <PackageReference Include="Grpc.Tools" Version="2.45.0">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
  </ItemGroup>

  <ItemGroup>
    <Protobuf Include="Protos\greet.proto" GrpcServices="Client" />
  </ItemGroup>

</Project>


5.  빌드/다시빌드
빌드 하게되면 proto 파일을 이용해 c# 코드가 생성된다. (솔루션 탐색기에서 표시되지 않음)


6. 서버 연결 및 통신

using System.Threading.Tasks;

using Grpc.Net.Client;

using GrpcClient;

using var channel = GrpcChannel.ForAddress("http://localhost:5253");
var client = new Greeter.GreeterClient(channel);
var reply = await client.SayHelloAsync(new HelloRequest { Name = "GreeterClient" });
Console.WriteLine("Greeting: " + reply.Message);
Console.WriteLine("Press any key to exit...");
Console.ReadKey();

https 로 연결하면 SSL 인증서를 요구한다.
SayHelloAsync 로 서버쪽에 요청을 하게되면 서버측에서는 받은 메세지앞에 Hello 를 붙여 반환한다.

아래는 서버와 클라이언트간에 테스트 결과


소스 : https://github.com/kei-soft/GrpcSample

참고 링크 : https://docs.microsoft.com/ko-kr/aspnet/core/tutorials/grpc/grpc-start?view=aspnetcore-6.0&tabs=visual-studio

반응형
728x90
반응형

쿼리문 하나에 parameter 를 변경해 일일히 쿼리하는 일을 아래처럼 하면 dapper 가 알아서 해준다.

#region MultiUpdate
/// <summary>
/// Multipul Update
/// </summary>
private void MultiUpdate()
{
    string sql = "UPDATE TestTable SET DATA1 = @DATA1 WHERE ID = @ID;";

    using (IDbConnection db = new SqlConnection(this.connectionString))
    {
        int rowsAffected = db.Execute(sql,
            new[]
            {
                    new { ID = 1, DATA1 = "UPDATEA1" },
                    new { ID = 2, DATA1 = "UPDATEA2" },
            }
        );
    }
}
#endregion
#region MultiDelete
/// <summary>
/// Multipul Delete
/// </summary>
private void MultiDelete()
{
    string sql = "DELETE FROM TestTable WHERE ID = @ID;";

    using (IDbConnection db = new SqlConnection(this.connectionString))
    {
        int rowsAffected = db.Execute(sql,
            new[]
            {
                    new { Id = 1 },
                    new { Id = 2 }
            }
        );
    }
}
#endregion
반응형

'C#' 카테고리의 다른 글

[C#] gRPC Stream Server/Client 만들기  (0) 2022.05.04
[C#] gRPC Server/Client 만들기  (0) 2022.05.04
[C#/Dapper] Multi Delete, Multi Update  (0) 2022.04.23
[C#/Dapper] Multi Select  (0) 2022.04.23
[C#/Dapper] Bulk Insert (List<T> Insert)  (0) 2022.04.23
[C#/Dapper] Dynamic Parameter  (0) 2022.04.23
728x90
반응형

dapper 를 이용하면 select 문을 여러개 사용해 여러 결과를 얻어올수 있다.

using (IDbConnection db = new SqlConnection(this.connectionString))
{
    db.Open();

    // ■ Multi Result
    sql = @"
SELECT * FROM TestTable WHERE ID = @ID
SELECT * FROM TestTable2 WHERE ID = @ID";

    using (var multi = db.QueryMultiple(sql, new { id = 7 }))
    {
         // 순서를 맞춰야 함
         var multiData1 = multi.Read<TestDataModel>().ToList();
         var multiData2 = multi.Read<TestDataModel2>().ToList();
    }
}

쿼리 순서에 맞춰 Read 를 호출해 데이터를 가져오면 된다.

반응형

'C#' 카테고리의 다른 글

[C#] gRPC Server/Client 만들기  (0) 2022.05.04
[C#/Dapper] Multi Delete, Multi Update  (0) 2022.04.23
[C#/Dapper] Multi Select  (0) 2022.04.23
[C#/Dapper] Bulk Insert (List<T> Insert)  (0) 2022.04.23
[C#/Dapper] Dynamic Parameter  (0) 2022.04.23
[C#/Dapper] Dynamic Result  (0) 2022.04.23

+ Recent posts