Asp.Net 코어 의 Middle Ware 사상 을 이용 하여 복잡 한 업무 절 차 를 어떻게 처리 하 는 지 상세 하 게 설명 합 니 다.

머리말
최근 에 Asp.Net Core 의 MiddleWare 사상 을 이용 하여 회사 의 오래된 코드 를 재 구성 하고 여기 서 제 디자인 방향 을 공유 하여 복잡 한 절차 업 무 를 처리 하 는 데 도움 이 되 기 를 바 랍 니 다.
배경
하나의 프로 세 스 가 인 터 페 이 스 를 초기 화하 고 인터페이스 에 들 어 오 는 프로 세 스 유형 에 따라 서로 다른 작업 을 해 야 합 니 다.
1.어떤 일 은 어떤 유형의 절차 든 지 해 야 하 는(공유)것 이 고,어떤 일 은 특정한 절차 특유 의 것 이다.
2.각 처리 임 무 는 기본적으로 끼 워 넣 는 관계 가 존재 하지 않 기 때문에 코드 는 기본적으로 유수 장부 식 이다.
3.절차 의 종류 가 비교적 많 고 코드 에서 if 또는 switch 판단 이 큰 지면 을 차지한다.
4.이런 처리 업 무 는 크게 세 가지 로 나 눌 수 있 는데 초기 준비 작업(파라미터 검사 등),처리 중인 작업(데이터 베이스 업데이트,데이터 삽입 등),마무리 작업(로그 기록,알림 등)으로 나 눌 수 있다.
Asp.Net 코어 중의 MiddleWare
두 번 째,유수 장부 식 코드 를 주의 하 세 요.이것 은 저 로 하여 금 을 생각 나 게 합 니 다.그리고 Asp.Net Core 의 Middle Ware 는 바로 이 파이프 에 놓 여 있 습 니 다.
다음 그림 보기:

middleware 1,middleware 2,middleware 3 이 세 개의 중간 부품 을 하나의 중간 부품 의 집합(PipeLine,파이프)에 놓 고 질서 있 게 배열 합 니 다.Request 는 1 이 2 에서 3 으로 흐 르 도록 요청 합 니 다.이에 따라 발생 하 는 Response 는 아래 에서 이 로 흘러 나 옵 니 다.
이 Request 와 Resopnse 는 우리 가 자주 보 는 Context 컨 텍스트 에 봉 인 됩 니 다.Context 는 미들웨어 1,미들웨어 1 처리 후 Context 를 미들웨어 2>>>>>로 전달 합 니 다.   마지막 까지 이렇게 전해 진다.
startup 의 configure 에서 자주 호출 되 는 app.use()방법 은 이 집합 에 middleware 를 추가 하 는 것 입 니 다.Context 가 들 어가 면 이 middleware 에 의 해 처리 되 어야 합 니 다.
내 가 이렇게 말 하 는 지 모 르 겠 지만,여러분 은 이런 파이프 모형 으로 임 무 를 처리 하 는 개념 이 있 습 니까?
코드 판독
모르다괜찮아,그럼 코드 를 결합 해 보 자.
위 에서 말 했 듯 이 모든 MiddleWare 는 Context 를 자신의 몸 에서 한 번 훑 어보 고 다음 중간 부품 을 주동 적 으로 호출한다.
그래서 중간 부품 은 무엇 입 니까?들 어 오 는 것 도 Context 이 고 들 어 오 는 것 도 Context 방법 인가요?아니 야!
전 송 된 것 은 의뢰 이 고 전 송 된 것 도 의뢰 입 니 다.이 전 송 된 의뢰 의 매개 변 수 는 Context 입 니 다.이 의뢰 는 다음 과 같 습 니 다.

/// <summary>
 ///         
 /// </summary>
 /// <param name="context"></param>
 /// <returns></returns>
 public delegate Task PipeLineDelegate<in TContext>(TContext context);
그래서 중간 부품 은 다음 과 같은 Func 입 니 다.다음 중간 부품(의뢰)을 호출 하 는 중임 을 맡 고 있 습 니 다.

Func<PipeLineDelegate<TContext>, PipeLineDelegate<TContext>>
파 이 프 는 무엇 일 까?  Func 의 집합 입 니 다.다음 과 같 습 니 다.

IList<Func<PipeLineDelegate<TContext>, PipeLineDelegate<TContext>>> _components = new List<Func<PipeLineDelegate<TContext>, PipeLineDelegate<TContext>>>();
저희 가 Startup 방법 에 있 는 Configure 방법 에 있 는 Use 는 뭐 하 는 거 죠?사실은 위 에 있 는 파 이 프 를 주 는 거 야components 에 func 를 추가 합 니 다.다음 과 같 습 니 다.

public IPipeLineBuilder<TContext> Use(Func<PipeLineDelegate<TContext>, PipeLineDelegate<TContext>> func)
  {
   _components.Add(func);
   return this;
  }
하지만 오늘 의 Use 에 서 는 기 존의 Use 를 다시 불 러 오고 싶 습 니 다.다음 과 같 습 니 다.

public IPipeLineBuilder<TContext> Use(Action<TContext> action, int? index = null)
  {
   Func<PipeLineDelegate<TContext>, PipeLineDelegate<TContext>> pipleDelegate = next =>
   {
    return context =>
    {
     action.Invoke(context);
     return next.Invoke(context);
    };
   };
   if (index.HasValue)
    if (index.Value > _components.Count)
     throw new Exception("            ");
    else
    {
     _components.Insert(index.Value, pipleDelegate);
    }
   else
   {
    _components.Add(next =>
    {
     return context =>
     {
      action.Invoke(context);
      return next.Invoke(context);
     };
    });
   }
   return this;
  }
다시 불 러 온 후에 들 어 오 는 것 은 Actionaction 이 되 었 습 니 다.외부 에서 자신 이 진정 으로 처리 해 야 할 업무 에 전념 하고 싶 기 때문에 다음 middleware 의 일 을 방법 내부 로 밀봉 하고 외부 에서 관심 을 가지 지 않 아 도 됩 니 다.또한 들 어 오 는 index 를 통 해 삽 입 된 미들웨어 의 위 치 를 지정 하여 업무 수행 순 서 를 제어 할 수 있 습 니 다.
마지막 으로 들 어 오 는 의뢰 를 연결 해 야 합 니 다.이것 이 바로 파이프 의 Build 작업 입 니 다.코드 는 다음 과 같 습 니 다.

public PipeLineDelegate<TContext> Build()
  {
   var requestDelegate = (PipeLineDelegate<TContext>)(context => Task.CompletedTask);

   foreach (var func in _components.Reverse())
    requestDelegate = func(requestDelegate);

   return requestDelegate;
  }
여기까지 파이프 와 관련 된 차 이 는 많 지 않 습 니 다.그러면 저 는 위의 사상 을 어떻게 이용 하여 제 업 무 를 처리 합 니까?
업 무 를 처리 하 다 

처리 설명도
단계:
Ø 세 개의 처리 파 이 프 를 초기 화 합 니 다.
Ø 세 개의 파이프 에 공공 처리 임 무 를 주입 합 니 다.
Ø 들 어 오 는 프로 세 스 유형 에 따라 동적 으로 불 러 오 는 처리 방법 Handle().
Ø Handle 방법 은 세 개의 파이프 에 이 유형의 프로 세 스에 대응 하 는 특유 의 작업 을 주입 합 니 다.
Ø Build 세 개의 파이프.
Ø 이에 따라 준비 작업 파이프=>처리 중 파이프=>처리 후 파이프.
위의 절 차 는 아래 의 코드 로 요약 할 수 있다.

private void InitApproveFlow(ApproveFlowInitContext context)
  {
   var beforePipeLineBuilder = InitBeforePipeLine();
   var handlingPipeLineBuilder = InitHandlingPipeLine();
   var afterPipeLineBuilder = InitAfterPipeLine();

   RegisterEntityPipeLine(context.flowType, beforePipeLineBuilder, handlingPipeLineBuilder, afterPipeLineBuilder);

   var beforePipeLine = beforePipeLineBuilder.Build();
   var handlingPipeLine = handlingPipeLineBuilder.Build();
   var afterPipeLine = afterPipeLineBuilder.Build();
   
   beforePipeLine.Invoke(context);
   handlingPipeLine.Invoke(context);
   afterPipeLine.Invoke(context);
  }
그 중에서 RegisterEntityPipLine()방법 은 flow Type 동적 로드 에 대응 하 는 클래스 에 따라 모든 클래스 가 하나의 공공 인 터 페 이 스 를 계승 하고 인 터 페 이 스 는 Handle 방법 을 드 러 냈 다.

private void RegisterEntityPipeLine(string flowType, IPipeLineBuilder<ApproveFlowInitContext> beforePipeLineBuilder,
   IPipeLineBuilder<ApproveFlowInitContext> handlingPipeLineBuilder,
   IPipeLineBuilder<ApproveFlowInitContext> afterPipeLineBuilder)
  {
   var handleClassName = ("     " + flowType).ToLower();
   var type = AppDomain.CurrentDomain.GetAssemblies()
    .Where(a => a.FullName.Contains("     "))
    .SelectMany(a =>
     a.GetTypes().Where(t =>
      t.GetInterfaces().Contains(typeof(        ))
     )
    ).FirstOrDefault(u =>
     u.FullName != null && u.Name.ToLower() == handleClassName
    );

   if (type == null)
    throw new ObjectNotFoundException("      [" + handleClassName + "]  ");

   var handle = (        )_serviceProvider.GetService(type);
   handle.Handle(beforePipeLineBuilder, handlingPipeLineBuilder, afterPipeLineBuilder);
  }
핸들 링 방법 중 에 또 뭐 했 죠?

public void Handle(IPipeLineBuilder<ApproveFlowInitContext> beforePipeLineBuilder, IPipeLineBuilder<ApproveFlowInitContext> handlingPipeLineBuilder, IPipeLineBuilder<ApproveFlowInitContext> afterPipeLineBuilder)
  {
   HandleBefore(beforePipeLineBuilder);
   Handling(handlingPipeLineBuilder);
   HandleAfter(afterPipeLineBuilder);
  }
각각 세 개의 파이프 에 전,중,후 대응 하 는 작업 을 추가 합 니 다.
Q&A
Q1:처리 작업 이 이전 처리 작업 의 처리 결과 에 의존 하면 어떻게 합 니까?
PipeLine Delegate의 TContext 는 대상 입 니 다.이 대상 에 해당 하 는 속성 을 추가 할 수 있 습 니 다.상류 작업 처리 작업 과 Context 의 속성 에 값 을 부여 하여 하류의 작업 에 사용 할 수 있 습 니 다.
Q2:만약 어떤 임무 가 다른 임무 전에 수행 되 어야 한다 면 어떻게 합 니까?
PipeLine Builder.Use()에 Index 인자 가 있 습 니 다.이 매개 변 수 를 통 해 작업 을 삽입 할 위 치 를 지정 할 수 있 습 니 다.
Q3:파이프 의 유 니 버 설 성 을 확보 하면(특정한 업무 에 국한 되 지 않 음)?
TContext 는 일반적인 형태 로 서로 다른 작업 에 대응 하 는 TContext 를 만 들 면 서로 다른 업무 에서 PipleLine 의 재 활용 을 실현 할 수 있 습 니 다.
총결산
이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.

좋은 웹페이지 즐겨찾기