상속된 클래스에서 종속성 주입 처리
// without DI
public class OrderController : Controller
{
public ActionResult Post(Order order)
{
using (var dbContent = new MyDbContext())
{
dbContext.Orders.Add(order);
dbContent.SaveChanges();
return Ok();
}
}
public ActionResult Get()
{
using (var dbContext = new MyDbContext())
{
var orders = dbContext.Orders.ToList();
return new JsonResult(orders);
}
}
}
// with DI
public class OrderController : Controller
{
private readonly MyDbContext _dbContext;
public OrderController(MyDbContext dbContext)
{
_dbContext = dbContext;
}
public ActionResult Post(Order order)
{
_dbContext.Orders.Add(order);
_dbContent.SaveChanges();
return Ok();
}
public ActionResult Get()
{
var orders = _dbContext.Orders.ToList();
return new JsonResult(orders);
}
}
그러나 나는 최근에 DI가 상속된 클래스에 종속성 주입이 될 수 있는 실제적인 고통이 될 수 있는 사용 사례를 발견했습니다.
문제
저는 최근에 Mediatr 패키지로 많은 작업을 해왔습니다. 요청/요청 처리기 패턴을 사용하여 시스템에서 명령을 실행했습니다(Jason Taylor's Clean Architecture solution에서 영감을 받음).
저는 일반적으로 공통 종속성과 기능을 포함하는 RequestHandler 기본 클래스를 만듭니다. 그런 다음 각 구체적인 요청 핸들러는 이 기본 클래스에서 상속할 수 있습니다.
public abstract class RequestHandler<TRequest, TResponse> : IRequestHandler<TRequest, TResponse>
where TRequest : IRequest<TResponse>
{
public RequestHandler(IApplicationDbContext dbContext)
{
DbContext = dbContext;
}
protected IApplicationDbContext DbContext { get; }
public abstract Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken);
}
public MyRequestHandler : RequestHandler<MyRequest, MyResponse>
{
public MyRequestHandler(IApplicationDbContext dbContext) : base(dbContext) { }
public override Task<MyResponse> Handle(MyRequest request, CancellationToken cancellationToken)
{
// handler logic
}
}
기본 클래스에 더 많은 종속성을 추가하려고 할 때 문제가 발생합니다. 이제 모든 구체적인 요청 핸들러를 살펴보고 생성자를 업데이트하여 새로운 종속성도 가져와야 합니다. 다행히 코드가 누락되면 컴파일되지 않으므로 런타임 오류의 위험은 없지만 모든 단일 요청 핸들러를 업데이트해야 하는 것은 여전히 엄청나게 지루한 작업입니다. 또한 클래스의 의도를 모호하게 만드는 매우 큰 생성자로 끝날 수 있습니다.
public abstract class RequestHandler<TRequest, TResponse> : IRequestHandler<TRequest, TResponse>
where TRequest : IRequest<TResponse>
{
public RequestHandler(IApplicationDbContext dbContext, ICurrentUser currentUser)
{
DbContext = dbContext;
CurrentUser = currentUser;
}
protected IApplicationDbContext DbContext { get; }
protected ICurrentUser CurrentUser { get; }
public abstract Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken);
}
public MyRequestHandler : RequestHandler<MyRequest, MyResponse>
{
public MyRequestHandler(IApplicationDbContext dbContext, ICurrentUser currentUser) : base(dbContext, currentUser) { }
public override Task<MyResponse> Handle(MyRequest request, CancellationToken cancellationToken)
{
// handler logic
}
}
솔루션 - 종속성 집계
이 문제에 대한 해결책은 정말 간단합니다. 종속성을 직접 주입하는 대신 종속성을 포함하는 새 클래스(집계라고 함)를 만들고 대신 주입합니다.
public interface IDependencyAggregate
{
IApplicationDbContext DbContext { get; }
ICurrentUser { get; }
}
public class DependencyAggregate : IDependencyAggregate
{
public DependencyAggregate(IApplicationDbContext dbContext, ICurrentUser currentUser)
{
DbContext = dbContext;
CurrentUser = currentUser;
}
public IApplicationDbContext DbContext { get; }
public ICurrentUser CurrentUser { get; }
}
public abstract class RequestHandler<TRequest, TResponse> : IRequestHandler<TRequest, TResponse>
where TRequest : IRequest<TResponse>
{
public RequestHandler(IDependencyAggregate aggregate)
{
DbContext = aggregate.DbContext;
CurrentUser = aggregate.CurrentUser;
}
protected IApplicationDbContext DbContext { get; }
protected ICurrentUser CurrentUser { get; }
public abstract Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken);
}
public MyRequestHandler : RequestHandler<MyRequest, MyResponse>
{
public MyRequestHandler(IDependencyAggregate aggregate) : base(aggregate) { }
public override Task<MyResponse> Handle(MyRequest request, CancellationToken cancellationToken)
{
// handler logic
}
}
이제 새 종속성을 추가하려는 경우 코드를 변경해야 하는 유일한 위치는 DependencyAggregate 클래스와 RequestHandler 기본 클래스입니다(상속된 클래스를 변경할 필요가 없음).
결론
이 게시물에서는 기본 클래스에 주입할 종속성 집계 클래스를 만들어 상속된 클래스에서 종속성 주입을 관리하는 간단한 방법을 설명했습니다. 이렇게 하면 상속된 모든 클래스를 변경해야 하는 경우 새 종속성을 쉽게 도입할 수 있습니다.
주로 풀 스택 .NET 및 Vue 웹 개발에 대해 게시합니다. 게시물을 놓치지 않으려면 이 블로그 및 subscribe to my newsletter 을 팔로우하십시오. 이 게시물이 도움이 되셨다면 좋아요와 공유 부탁드립니다. 에서 나를 찾을 수도 있습니다.
Reference
이 문제에 관하여(상속된 클래스에서 종속성 주입 처리), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/dr_sam_walpole/handling-dependency-injection-in-inherited-classes-4ilj
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
public abstract class RequestHandler<TRequest, TResponse> : IRequestHandler<TRequest, TResponse>
where TRequest : IRequest<TResponse>
{
public RequestHandler(IApplicationDbContext dbContext)
{
DbContext = dbContext;
}
protected IApplicationDbContext DbContext { get; }
public abstract Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken);
}
public MyRequestHandler : RequestHandler<MyRequest, MyResponse>
{
public MyRequestHandler(IApplicationDbContext dbContext) : base(dbContext) { }
public override Task<MyResponse> Handle(MyRequest request, CancellationToken cancellationToken)
{
// handler logic
}
}
public abstract class RequestHandler<TRequest, TResponse> : IRequestHandler<TRequest, TResponse>
where TRequest : IRequest<TResponse>
{
public RequestHandler(IApplicationDbContext dbContext, ICurrentUser currentUser)
{
DbContext = dbContext;
CurrentUser = currentUser;
}
protected IApplicationDbContext DbContext { get; }
protected ICurrentUser CurrentUser { get; }
public abstract Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken);
}
public MyRequestHandler : RequestHandler<MyRequest, MyResponse>
{
public MyRequestHandler(IApplicationDbContext dbContext, ICurrentUser currentUser) : base(dbContext, currentUser) { }
public override Task<MyResponse> Handle(MyRequest request, CancellationToken cancellationToken)
{
// handler logic
}
}
이 문제에 대한 해결책은 정말 간단합니다. 종속성을 직접 주입하는 대신 종속성을 포함하는 새 클래스(집계라고 함)를 만들고 대신 주입합니다.
public interface IDependencyAggregate
{
IApplicationDbContext DbContext { get; }
ICurrentUser { get; }
}
public class DependencyAggregate : IDependencyAggregate
{
public DependencyAggregate(IApplicationDbContext dbContext, ICurrentUser currentUser)
{
DbContext = dbContext;
CurrentUser = currentUser;
}
public IApplicationDbContext DbContext { get; }
public ICurrentUser CurrentUser { get; }
}
public abstract class RequestHandler<TRequest, TResponse> : IRequestHandler<TRequest, TResponse>
where TRequest : IRequest<TResponse>
{
public RequestHandler(IDependencyAggregate aggregate)
{
DbContext = aggregate.DbContext;
CurrentUser = aggregate.CurrentUser;
}
protected IApplicationDbContext DbContext { get; }
protected ICurrentUser CurrentUser { get; }
public abstract Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken);
}
public MyRequestHandler : RequestHandler<MyRequest, MyResponse>
{
public MyRequestHandler(IDependencyAggregate aggregate) : base(aggregate) { }
public override Task<MyResponse> Handle(MyRequest request, CancellationToken cancellationToken)
{
// handler logic
}
}
이제 새 종속성을 추가하려는 경우 코드를 변경해야 하는 유일한 위치는 DependencyAggregate 클래스와 RequestHandler 기본 클래스입니다(상속된 클래스를 변경할 필요가 없음).
결론
이 게시물에서는 기본 클래스에 주입할 종속성 집계 클래스를 만들어 상속된 클래스에서 종속성 주입을 관리하는 간단한 방법을 설명했습니다. 이렇게 하면 상속된 모든 클래스를 변경해야 하는 경우 새 종속성을 쉽게 도입할 수 있습니다.
주로 풀 스택 .NET 및 Vue 웹 개발에 대해 게시합니다. 게시물을 놓치지 않으려면 이 블로그 및 subscribe to my newsletter 을 팔로우하십시오. 이 게시물이 도움이 되셨다면 좋아요와 공유 부탁드립니다. 에서 나를 찾을 수도 있습니다.
Reference
이 문제에 관하여(상속된 클래스에서 종속성 주입 처리), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/dr_sam_walpole/handling-dependency-injection-in-inherited-classes-4ilj
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(상속된 클래스에서 종속성 주입 처리), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/dr_sam_walpole/handling-dependency-injection-in-inherited-classes-4ilj텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)