sourcecode

Microsoft의 OWIN 구현에서 확장 메서드 CreatePerOwinContext의 목적은 무엇입니까?

copyscript 2023. 8. 2. 09:19
반응형

Microsoft의 OWIN 구현에서 확장 메서드 CreatePerOwinContext의 목적은 무엇입니까?

저는 ASP 신입생입니다.NET, 그리고 현재 학습 중인 ASP.NET 아이덴티티.마이크로소프트의 OWIN 구현 위에 구축되어 있다는 것을 알고 있으며, 저도 여전히 그것을 배우고 있습니다.그래서 저는 Owin 시작 코드에서 CreatePerOwinContext 확장 메서드를 발견했는데, 사용 목적이 명확하지 않습니다.일종의 의존성 주입 용기입니까?그 방법의 진짜 목적은 무엇입니까?어떤 경우에 그것을 적용해야 합니까?

CreatePerOwinContext는 응용 프로그램이 지정된 유형의 새 인스턴스를 가져오는 데 사용할 정적 콜백을 등록합니다.
이 콜백은 요청당 한 번씩 호출되며 응용 프로그램 전체에서 사용할 수 있도록 개체/개체를 OwinContext에 저장합니다.

IdentityDbContext의 구현을 직접 정의했다고 가정해 보겠습니다.

public class ApplicationDatabaseContext : IdentityDbContext<MyApplicationUser, MyRole, Guid, MyUserLogin, MyUserRole, MyUserClaim>
{
    public ApplicationDatabaseContext() : base("<connection string>")
    {
    }

    public static ApplicationDatabaseContext Create()
    {
        return new ApplicationDatabaseContext();
    }

        protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
        {
        base.OnModelCreating(modelBuilder);

        // Customize your table creation here.

            #region USERS - INFOS

        modelBuilder.Entity<UserInfo>()
            .Property(p => p.FirstName)
            .HasColumnType("varchar")
            .HasMaxLength(70);

        modelBuilder.Entity<UserInfo>()
            .Property(p => p.LastName)
            .HasColumnType("varchar")
            .HasMaxLength(70);

        modelBuilder.Entity<UserInfo>()
            .Property(p => p.Address)
            .HasColumnType("varchar")
            .HasMaxLength(100);

        modelBuilder.Entity<UserInfo>()
            .Property(p => p.City)
            .HasColumnType("varchar")
            .HasMaxLength(100);

        modelBuilder.Entity<UserInfo>()
            .ToTable("UsersInfo");

        #endregion  
        }

        public DbSet<UserInfo> UsersInfo { get; set; }
}

UserManager 구현:

public class ApplicationUserManager : UserManager<MyApplicationUser, Guid>
{
    public ApplicationUserManager(IUserStore<MyApplicationUser, Guid> store) : base(store)
        {
        }

        public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
        {
            var manager = new ApplicationUserManager(new MyUserStore(context.Get<ApplicationDatabaseContext>()));

            manager.UserValidator = new UserValidator<MyApplicationUser, Guid>(manager)
            {
                AllowOnlyAlphanumericUserNames = false,
                RequireUniqueEmail = true
            };

            manager.PasswordValidator = new PasswordValidator()
            {
                RequiredLength = 6,
                RequireNonLetterOrDigit = false,    
                // RequireDigit = true,
                RequireLowercase = false,
                RequireUppercase = false,
            };

            var dataProtectionProvider = options.DataProtectionProvider;

            if (dataProtectionProvider != null)
            {
                manager.UserTokenProvider = new DataProtectorTokenProvider<MyApplicationUser, Guid>(dataProtectionProvider.Create("PasswordReset"));
            }

            return (manager);
        }
}

Owin Startup에서 콜백을 등록합니다.

// IAppBuilder app

app.CreatePerOwinContext<ApplicationDatabaseContext>(ApplicationDatabaseContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);

정적 메서드를 호출합니다.

public static ApplicationDatabaseContext Create()
{
    return new ApplicationDatabaseContext();
}

그리고.

public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
{
    ...
}

이제 간단한 방법으로 데이터베이스 컨텍스트 및 사용자 관리자에 액세스할 수 있습니다.

ApplicationDatabaseContext dbContext = context.OwinContext.Get<ApplicationDatabaseContext>();
ApplicationUserManager userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();

API 컨트롤러(WebApi를 사용하는 경우)에서 다음을 수행합니다.

IAuthenticationManager authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
ApplicationUserManager applicationUserManager = HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>();

그 방법의 진짜 목적은 무엇입니까?어떤 경우에 그것을 적용해야 합니까?

당신의 질문에 더 직접적으로 대답하자면, 이것은 쓸모가 없습니다.

  1. 그것은 어떤 사람들이 즐겨 사용하는 일종의 IoT 공장입니다.
  2. 이것은 당신이 선택한 것보다 그들의 것(IOC)을 사용하게 만듭니다.
  3. (저는 IoC를 좋아하지 않습니다. 따뜻하고 퍼지를 느끼고 "건축"이라는 용어를 사용하고 싶은 사람들에게 반패턴처럼 느껴집니다.)
  4. 하지만 진지하게, 이 패턴은 IoT 인터페이스가 아니라 IoC 정적 공장 기능을 합니다!누구의 생각입니까?공장 기능을 직접 사용하는 것이 어떻습니까? (호출을 기억해야 , (Google)에서 호출, F12 호출을 기억해야 .Get아무 도움이 되지 않습니다.

그렇다면 당신은 무엇을 대신 해야 합니까?

개인적으로, 저는 OO를 이용하는 것을 좋아합니다, OO 기억하시나요?페퍼리지 농장은 기억합니다.OOO를 사용하면 제어 상태를 유지하고 디버그, 로그 및 확장을 수행할 수 있습니다.

public class BaseApiController : ApiController
{
    private AppDbContext _db = null;

    protected AppDbContext db
    {
        get
        {
            if (_db == null)
            {
                _db = AppDbContext.Create(); //Hey look a proper factory that you can extend with other overloads! And I can debug this line - neat!
            }
            return _db;
        }

    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            if (_db != null)
                _db.Dispose();
        }
    }

}

이 모든 것은 시간 낭비일 수 있습니다. 만약 누군가가 마이크로소프트 엔지니어들이 이것을 왜 넣었는지에 대한 문서를 발견한다면, 그들은 그럴만한 이유가 있을지도 모릅니다. 하지만 저는 그것이 의심스럽습니다. 그 동안에 이 답변을 올리도록 합시다.

업데이트 1

Microsoft가 이 기능을 제공하는 이유는 다음과 같습니다. https://blogs.msdn.microsoft.com/webdev/2014/02/12/per-request-lifetime-management-for-usermanager-class-in-asp-net-identity/

기본적으로 사용자 관리자와 모든 사용자는 이러한 구조를 위해 구축됩니다.보안 검사는 파이프라인에서 발생하므로 폐기물을 줄이기 위해 요청에 연결된 싱글톤을 사용하는 것이 어떻습니까?숨겨져 있기 때문입니다.

기본 클래스에서 DB 컨텍스트의 인스턴스를 직접 생성하는 것이 좋습니다. 사용하기가 훨씬 깨끗합니다.원하는 경우 기본 클래스에 OwinContext에서 싱글톤을 검색하는 속성을 가질 수 있습니다.

이러한 고급 API 및 Authorization 특성 등을 해결하기 위해 얼마나 많은 시간을 낭비하고 있습니까?

public void DoSomething()
{
   DemandAuthenticated();
   DemandAuthorised(typeof(somethingClass), "DoSomething");
}

분명히, 저는 당신이 볼 수 있는 상세한 코드를 선호합니다.

업데이트 2

EF 컨텍스트는 싱글톤으로 보유되어서는 안 되며, IoC 또는 리포지토리 패턴을 통해 보유되어서는 안 됩니다.

일반적으로, 예 IoT는 상황에서 유용할 수 있습니다.하지만 특별히 dbContext를 위해서요?

EFDB 컨텍스트는 작업 단위이므로 수명이 짧아야 합니다.개체 캐시를 오래 실행하면 쿼리 속도가 느려지고 기본 데이터베이스에 대한 업데이트/삽입 속도가 느려집니다.수명이 짧도록 설계되었습니다.또한 EF 컨텍스트는 이미 느슨하게 결합되어 있습니다.연결 문자열에서 컨텍스트 뒤에 있는 RDBMS를 변경할 수 있으며 메모리만 사용할 수도 있습니다. 3) EF에는 매우 유연하고 표현력이 뛰어나며 안전한 LINQ가 있습니다.데이터베이스는 IoT의 비즈니스 수준 서비스가 아닙니다. 서비스가 데이터베이스와 통신하는 데 사용하는 도구입니다.아마도, 당신은 IoC를 통해 접속되는 일종의 서비스 IE 메일을 가지고 있을 것입니다.그러나 쿼리 완료 후 즉시 폐기되는 새로운 EF 컨텍스트를 사용하여 내부 데이터베이스에 액세스해야 합니다.위의 1-4를 고려할 때, 우리는 중간 인터페이스 계층(서비스 또는 저장소)이 애초에 EF를 사용함으로써 얻을 수 있는 모든 이점을 망치는 것을 원치 않습니다.

사용할 수 있습니다.typeof다음과 같은 이름을 얻기 위해:

HttpContext.GetOwinContext().Get<ApplicationDbContext>(typeof(ApplicationDbContext).ToString());

언급URL : https://stackoverflow.com/questions/26626120/what-is-the-purpose-of-the-extension-method-createperowincontext-in-owin-impleme

반응형