2022. 12. 26. 00:00ㆍASPNET/ASPNET 7
ASPNET Core 는 기본적으로 Dependency Injection 을 이용하여 의존성을 분리 하고 있다.
https://yogingang.tistory.com/2
Dotnet 6 Dependency Injection
종속성 클래스와 해당 종속성 간의 Ioc (Inversion of Control)를 실현하는 기술로 DI (Dependency Injection) 라는 디자인 패턴을 지원한다. 종류 (서비스 수명) Transient : 요청할 때마다 만들어 짐, 요청이 끝날
yogingang.tistory.com
https://learn.microsoft.com/ko-kr/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-7.0
ASP.NET Core에서 종속성 주입
ASP.NET Core에서 종속성 주입을 구현하는 방법 및 사용 방법에 알아봅니다.
learn.microsoft.com
기본적으로 Lifecycle 이 있다.
Transient
: 매번 새로 Create 하는 방식
Scope
: 클라이언트 요청(연결)마다 한 번씩 서비스가 생성됨
Singleton
: 한번만 Create 하는 방식
자 이제 이전에 만들었던 Project 를 활용해 보자.
이전 Project 에서 Login 을 구현했었다
이부분에서 Token 을 생성하는 부분을 수정해 보자
1. TokenGenerator 라는 Token 생성 전용 class 를 만들자
2. TokenGenerator 을 Dependency Inejection 시스템에 등록하자
3. Login.cs 에서 해당 TokenGenerator 를 resolve 해서 사용하자
일단 아래와 같이 폴더 구조를 생성하자
Shared/Interfaces
그리고 해당 폴더 밑에 ITokenGenerator.cs 를 생성하자
Shared/Interfaces/ITokenGenerator.cs
namespace ApiServer.Shared.Interfaces;
public interface ITokenGenerator
{
string Create();
}
다음 폴더를 하나 더 생성하고 TokenGenerator.cs 를 구현하자
Shared/Utility/TokenGenerator.cs
using ApiServer.Shared.Interfaces;
namespace ApiServer.Shared.Utility;
public class TokenGenerator : ITokenGenerator
{
public string Create() => Guid.NewGuid().ToString("N");
}
이제 위의 TokenGenerator 을 DI 시스템에 Register 하겠다.
TokenGenerator 는 ThreadSafe 하며 ReenTrant 하기 때문에 Singleton 방식으로 등록하겠다.
Program.cs
using ApiServer.Shared.Interfaces;
using ApiServer.Shared.Utility;
...
builder.Services.AddSingleton<ITokenGenerator,TokenGenerator>();
이제 Login 에 이것을 적용해 보자
User/Login.cs
using ApiServer.Shared.Interfaces;
using MediatR;
using System.Runtime.CompilerServices;
namespace ApiServer.Features.User;
public class Login
{
public class Command : IRequest<Response>
{
public string Id { get; set; } = string.Empty;
public string Pasword { get; set; } = string.Empty;
}
public class Response
{
public bool Result { get; set; }
public Error? Error { get; set; }
public string? AccessToken { get; set; }
}
public class Error
{
public string Code { get; set; } = string.Empty;
public string Message { get; set; } = string.Empty;
}
public class CommandHandler : IRequestHandler<Command, Response>
{
private readonly ITokenGenerator _tokenGenerator;
// ITokenGenerator 를 Constructor injection
public CommandHandler(ITokenGenerator tokenGenerator)
{
_tokenGenerator = tokenGenerator;
}
public Task<Response> Handle(Command request, CancellationToken cancellationToken)
{
var response = new Response { Result = false };
string? accessToken = null;
if (request.Pasword == "1234")
{
//accessToken = Guid.NewGuid().ToString("N"); // 기존 코딩 comment
accessToken = _tokenGenerator.Create(); // DI 를 통해 가져온 TokenGenerator 를 사용
response.Result = true;
}
else
{
response.Error = new Error()
{
Code = "02",
Message = $"Login Failed, check your password"
};
}
response.AccessToken = accessToken;
return Task.FromResult(response);
}
}
}
Scrutor
ASPNET core 의 Dependency Injection (이후 DI 로 칭함) System 은 편리한 시스템이지만
Register 하려는 class 가 늘어날 수록 관리 하기가 점점 힘들어진다.
또한 하나의 project 가 아닌 여러 project 로 이루어져 있고 이들 모두를 관리하려면
정말 복잡한 형태가 되어 버린다.
그래서 이러한 단점을 개선한고 자동으로 class 가 DI system 에 Register 하는 방법이 있다.
3rd party libry 들이 있는데 우리는 그중에 Scrutor 을 이용하여 이를 구현할 것이다.
개발자 명령 프롬프트로 이동
Ctrl + ` 또는 View -> Terminal click -> 개발자 명령 프롬프트로 이동
개발자 명령 프롬프트에서 프로젝트 폴더로 이동
**이미 프로젝트 폴더에 있다면 이동하지 않아도 된다. **
(현재 [솔루션명].sln 파일이 있는 폴더라면 [프로젝트명].csproj 파일이 있는 폴더로 이동)
다음 실행
dotnet add package Scrutor
의존성 주입을 위한 interface 추가
Shared-->Injectables 폴더 추가 -> Injectable.cs 추가 -> 코드 수정
namespace ApiServer.Shared.Injectables;
public interface IInjectableService { }
public interface ITransient : IInjectableService { }
public interface IScoped : IInjectableService { }
public interface ISingleton : IInjectableService { }
Program.cs
using ApiServer.Shared.Injectables;
using ApiServer.Shared.Interfaces;
...
//builder.Services.AddSingleton<ITokenGenerator,TokenGenerator>(); // comment 처리
builder.Services.Scan(scan => scan
.FromAssemblies(AssemblyHelper.GetAllAssemblies(SearchOption.AllDirectories))
.AddClasses(
classes => classes.AssignableTo<ITransient>()
)
.AsSelfWithInterfaces()
.WithTransientLifetime()
.AddClasses(
classes => classes.AssignableTo<IScoped>()
)
.AsSelfWithInterfaces()
.WithScopedLifetime()
.AddClasses(
classes => classes.AssignableTo<ISingleton>())
.AsSelfWithInterfaces()
.WithSingletonLifetime()
);
Shared/Interfaces/ITokenGenerator.cs
using ApiServer.Shared.Injectables;
namespace ApiServer.Shared.Interfaces;
public interface ITokenGenerator : ISingleton
{
string Create();
}
그리고 실행하면 이전 동작과 똑같이 동작한다.
즉 이제부터는 Injectable.cs 에 정의한 ITransient, IScoped, ISingleton 을 상속하면 자동으로
해당 Lifecyle 에 맞게 DI 시스템에 register 된다.
앞으론 이걸 적극 활용하자
관련영상
'ASPNET > ASPNET 7' 카테고리의 다른 글
Rest API Template 만들기 - EP 05(AccessToken, RefreshToken with JWT) (0) | 2023.01.02 |
---|---|
Rest API Template 만들기 - EP 04 (Logger Customize, Trace) (0) | 2022.12.29 |
Rest API Template 만들기 - EP 02 (Vertical Slice, MediatR) (0) | 2022.12.22 |
Rest API Template 만들기 - EP 01 (Create , Swagger, Logging) (0) | 2022.12.19 |
gRPC HealthCheck (0) | 2022.12.15 |