. net core 의 전형 적 인 디자인 모델 의 응용

10637 단어
. net core 의 전형 적 인 디자인 모델 의 응용
Intro
얼마 전에 우 리 는 23 가지 디자인 모델 을 소 개 했 는데 오늘 은. net core 소스 코드 에서 비교적 전형 적 인 디자인 모델 의 응용 을 공유 하 겠 습 니 다.
실례
책임 체인 모드
asp. net core 미들웨어 의 디자인 은 바로 책임 체인 모델 의 응용 과 변형 이다.
모든 미들웨어 는 수요 에 따라 요 구 를 처리 하고 요청 정보 에 따라 다음 미들웨어 에 전달 할 지 여 부 를 스스로 결정 할 수 있 습 니 다. 저도 이 시사 점 을 받 아 미들웨어 모델 코드 를 쉽게 구축 할 수 있 습 니 다. 이 글 을 참고 할 수 있 습 니 다.https://www.cnblogs.com/weihanli/p/12700006.html
중간 부품 예시:
app.UseStaticFiles();

app.UseResponseCaching();
app.UseResponseCompression();

app.UseRouting();

app.UseCors(builder => builder.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin());

app.UseAuthentication();
app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
    endpoints.MapControllerRoute(name: "areaRoute", "{area:exists}/{controller=Home}/{action=Index}");
    endpoints.MapDefaultControllerRoute();
});
PipelineBuilder 실제 예시:
var requestContext = new RequestContext()
{
    RequesterName = "Kangkang",
    Hour = 12,
};

var builder = PipelineBuilder.Create(context =>
        {
            Console.WriteLine($"{context.RequesterName} {context.Hour}h apply failed");
        })
        .Use((context, next) =>
        {
            if (context.Hour <= 2)
            {
                Console.WriteLine("pass 1");
            }
            else
            {
                next();
            }
        })
        .Use((context, next) =>
        {
            if (context.Hour <= 4)
            {
                Console.WriteLine("pass 2");
            }
            else
            {
                next();
            }
        })
        .Use((context, next) =>
        {
            if (context.Hour <= 6)
            {
                Console.WriteLine("pass 3");
            }
            else
            {
                next();
            }
        })
    ;
var requestPipeline = builder.Build();
foreach (var i in Enumerable.Range(1, 8))
{
    Console.WriteLine();
    Console.WriteLine($"--------- h:{i} apply Pipeline------------------");
    requestContext.Hour = i;
    requestPipeline.Invoke(requestContext);
    Console.WriteLine("----------------------------");
    Console.WriteLine();
}

건설 자 모드
asp. net core 의 각종 PipelineBuilder, Builder / HostBuilderConfigurationBuilder 은 대부분 Builder 이자 Director 이 며, Builder 자체 가 최종 Builder Product 를 어떻게 구축 하 는 지 알 고 있다 Host / Configuration
var host = new HostBuilder()
    .ConfigureAppConfiguration(builder =>
    {
        //     
        builder
            .AddInMemoryCollection(new Dictionary()
            {
                {"UserName", "Alice"}
            })
            .AddJsonFile("appsettings.json")
            ;
    })
    .ConfigureServices((context, services) =>
    {
        //        
        services.AddSingleton();
        services.AddTransient();
        if (context.Configuration.GetAppSetting("XxxEnabled"))
        {
            services.AddSingleton();
        }
    })
    .Build()
    ;

공장 모드
주입 프레임 워 크 에 대량의 공장 모델 이 있 는 코드 에 의존 하고 서 비 스 를 등록 할 때 우 리 는 하나의 공장 방법 으로 서비스 인 스 턴 스 를 얻 을 수 있 습 니 다.
주입 에 의존 하 는 본질은 대상 의 생 성 을 IOC 용기 에 맡 기 는 것 이다. 따라서 IOC 용기 의 본질은 공장 이다. IOC 에서 서비스 인 스 턴 스 를 얻 는 과정 은 공장 이 대상 을 만 드 는 과정 이 고 서비스의 생명주기 에 따라 새로운 대상 을 만 들 지 기 존 대상 으로 돌아 갈 지 결정 할 뿐이다.
services.AddSingleton(sp => new Svc2(sp.GetRequiredService(), "xx"));

단일 모드
dotnet 에 서 는 순수한 굶 주 린 사람 모드 의 단일 모드 코드 TimeQueue 가 있 습 니 다.
class TimerQueue
{
    #region singleton pattern implementation

    // The one-and-only TimerQueue for the AppDomain.
    static TimerQueue s_queue = new TimerQueue();

    public static TimerQueue Instance
    {
        get { return s_queue; }
    }

    private TimerQueue()
    {
        // empty private constructor to ensure we remain a singleton.
    }

    #endregion

    // ...
}

https://referencesource.microsoft.com/#mscorlib/system/threading/timer.cs,49
dotnet 소스 코드 에는 게으름뱅이 식 단일 모드 도 있다.
사용 Interlocked 원자 조작
internal class SimpleEventTypes
    : TraceLoggingEventTypes
{
    private static SimpleEventTypes instance;

    internal readonly TraceLoggingTypeInfo typeInfo;

    private SimpleEventTypes(TraceLoggingTypeInfo typeInfo)
        : base(
            typeInfo.Name,
            typeInfo.Tags,
            new TraceLoggingTypeInfo[] { typeInfo })
    {
        this.typeInfo = typeInfo;
    }

    public static SimpleEventTypes Instance
    {
        get { return instance ?? InitInstance(); }
    }

    private static SimpleEventTypes InitInstance()
    {
        var newInstance = new SimpleEventTypes(TraceLoggingTypeInfo.Instance);
        Interlocked.CompareExchange(ref instance, newInstance, null);
        return instance;
    }
}

또 다른 예 는 주의해 야 한다. 아래 의 이런 방식 은 엄격 한 보증 을 하지 못 하고 하나의 사례 만 생 길 수 있다. 병발 이 비교적 높 은 상황 에서 같은 사례 가 아 닐 수도 있다. 이것 은 공장 모델 의 사례 라 고 할 수 있다.
static internal class ConfigurationManagerHelperFactory 
{
    private const string ConfigurationManagerHelperTypeString = "System.Configuration.Internal.ConfigurationManagerHelper, " + AssemblyRef.System;

    static private volatile IConfigurationManagerHelper s_instance;

    static internal IConfigurationManagerHelper Instance {
        get {
            if (s_instance == null) {
                s_instance = CreateConfigurationManagerHelper();
            }

            return s_instance;
        }
    }

    [ReflectionPermission(SecurityAction.Assert, Flags = ReflectionPermissionFlag.MemberAccess)]
    [SuppressMessage("Microsoft.Security", "CA2106:SecureAsserts", Justification = "Hard-coded to create an instance of a specific type.")]
    private static IConfigurationManagerHelper CreateConfigurationManagerHelper() {
        return TypeUtil.CreateInstance(ConfigurationManagerHelperTypeString);
    }
}

원형 모드
dotnet 에는 두 개의 데이터 구조 Stack / Queue 가 있 는데 이 두 개의 데 이 터 는 모두 ICloneable 인 터 페 이 스 를 실 현 했 고 내부 에서 깊 은 복 제 를 실현 했다 StackClone 방법 이 실현 되 었 다.
public virtual Object Clone()
{
    Contract.Ensures(Contract.Result() != null);
 
    Stack s = new Stack(_size);
    s._size = _size;
    Array.Copy(_array, 0, s._array, 0, _size);
    s._version = _version;
    return s;
}

자세 한 내용 은 참고 할 수 있 습 니 다.https://referencesource.microsoft.com/#mscorlib/system/collections/stack.cs,6acda10c5f8b128e
향원 모드
string intern (문자열 풀) 및 Array.Empty() / Array.Empty()
전략 모드
asp. net core 의 인증 과 권한 수 여 는 바로 전략 모델 의 응용 이 라 고 생각 합 니 다. [Authorize] 을 사용 할 때 기본 적 인 policy 를 사용 하고 사용 할 전략 [Authorize("Policy1")] 을 지정 할 수 있 습 니 다. 그러면 다른 전략 Policy1 을 사용 할 수 있 습 니 다. policy 는 비교적 간단 합 니 다.
policy 는 사용자 의 인증 정보 에 따라 권한 수여 방문 을 제어 하 는 데 사용 되 며, 인증 은 현재 컨 텍스트 (컨 텍스트 요청, 스 레 드 컨 텍스트, 환경 컨 텍스트 등) 의 정보 에 따라 인증 하여 사용자 정 보 를 얻 는 과정 입 니 다.
한편, 서로 다른 인증 모델 (Cookie / JWT / 사용자 정의 Token 등) 은 서로 다른 처리 방법 이다. 즉, 전략 모델 에서 서로 다른 알고리즘 이 실현 되 고 어떤 인증 모델 을 지정 하 는 지, 바로 어떤 알고리즘 을 사용 하여 사용자 정 보 를 얻 는 지 하 는 것 이다.
관찰자 모드
이벤트 (이벤트) 를 자주 사용 하여 결합 을 해제 하고 외부 코드 는 구독 이벤트 로 결합 을 해제 하여 내부 상태 에 대한 관찰 을 실현 합 니 다.Process 클래스 에 많은 이벤트 가 있 습 니 다. 다른 프로 세 스 의 출력, 오류 등 을 캡 처 할 수 있 습 니 다.
public event DataReceivedEventHandler OutputDataReceived;

public event DataReceivedEventHandler ErrorDataReceived;

보통 이 두 사건 에서 우 리 는 다른 프로 세 스 의 출력 정 보 를 얻 을 수 있 습 니 다. 그 밖 에 도 많은 종류의 이벤트 가 있 습 니 다. 당신 도 많이 사용 하 셨 을 것 이 라 고 믿 습 니 다.
조합 모드
WPF, WinForm 에는 모두 컨트롤 의 개념 이 있 는데 이런 컨트롤 의 디자인 은 조합 모델 의 응용 에 속 하고 모든 컨트롤 은 하나의 공 통 된 기본 클래스 에 계승 되 어 하나의 대상 과 조합 대상 을 그들의 공 통 된 기본 대상 으로 볼 수 있다.
교체 기 모드
c \ # 에서 교체 기 모드 를 정 의 했 습 니 다. 원본 정의:
//     
public interface IEnumerable
{
    /// Returns an enumerator that iterates through a collection.
    /// An  object that can be used to iterate through the collection.
    IEnumerator GetEnumerator();
}

//      
public interface IEnumerator
{
    /// Advances the enumerator to the next element of the collection.
    /// 
    ///  if the enumerator was successfully advanced to the next element;  if the enumerator has passed the end of the collection.
    /// The collection was modified after the enumerator was created.
    bool MoveNext();

    /// Gets the element in the collection at the current position of the enumerator.
    /// The element in the collection at the current position of the enumerator.
    object Current { get; }

    /// Sets the enumerator to its initial position, which is before the first element in the collection.
    /// The collection was modified after the enumerator was created.
    void Reset();
}

Array 와 List 는 각각 자신의 교체 기 를 실현 하 였 으 며, 관심 이 있 으 면 소스 코드 를 보 러 갈 수 있다.
More
. net core 에서 디자인 모델 응용 도 많 습 니 다. 위 에서 언급 한 이 몇 가지 모델 뿐만 아니 라 제 가 언급 한 이 몇 가지 부분 만 이 아 닙 니 다.
위 에 일부 예 시 는 dotnet framework 의 소스 코드 를 직접 사용 하 는 것 입 니 다. 많은 코드 가 유사 하기 때문에 사용 합 니 다.https://referencesource.microsoft.com 소스 코드
이상 은 모두 개인 적 인 이해 입 니 다. 만약 에 잘못 이 있 으 면 지적 해 주 십시오. 감사합니다. 더 많은 디자인 모델 응용의 소스 인 스 턴 스 를 보충 하 는 것 을 환영 합 니 다.
Reference
  • https://github.com/dotnet/aspnetcore
  • https://github.com/dotnet/extensions
  • https://github.com/dotnet/corefx
  • https://github.com/dotnet/aspnetcore
  • https://github.com/dotnet/runtime
  • 좋은 웹페이지 즐겨찾기