Quel est le but de la méthode d’extension CreatePerOwinContext dans l’implémentation OWIN par Microsoft

Je suis un débutant dans ASP.NET et j’apprends actuellement l’identité ASP.NET. Je sais qu’il est basé sur l’implémentation d’OWIN par Microsoft, et je continue également à l’apprendre. Donc, je suis tombé sur la méthode d’extension CreatePerOwinContext dans le code de démarrage Owin, et je ne vois pas clairement comment l’utiliser. Est-ce une sorte de conteneur d’dependency injection? Quel est le but réel de la méthode? Dans quel cas devrait-il être appliqué?

CreatePerOwinContext enregistre un rappel statique que votre application utilisera pour récupérer une nouvelle instance d’un type spécifié.
Ce rappel sera appelé une fois par requête et stockera l’object / les objects dans OwinContext afin que vous puissiez les utiliser dans toute l’application.

Disons que vous avez défini votre propre implémentation d’ IdentityDbContext :

public class ApplicationDatabaseContext : IdentityDbContext { public ApplicationDatabaseContext() : base("") { } 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() .Property(p => p.FirstName) .HasColumnType("varchar") .HasMaxLength(70); modelBuilder.Entity() .Property(p => p.LastName) .HasColumnType("varchar") .HasMaxLength(70); modelBuilder.Entity() .Property(p => p.Address) .HasColumnType("varchar") .HasMaxLength(100); modelBuilder.Entity() .Property(p => p.City) .HasColumnType("varchar") .HasMaxLength(100); modelBuilder.Entity() .ToTable("UsersInfo"); #endregion } public DbSet UsersInfo { get; set; } } 

et votre implémentation de UserManager :

 public class ApplicationUserManager : UserManager { public ApplicationUserManager(IUserStore store) : base(store) { } public static ApplicationUserManager Create(IdentityFactoryOptions options, IOwinContext context) { var manager = new ApplicationUserManager(new MyUserStore(context.Get())); manager.UserValidator = new UserValidator(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(dataProtectionProvider.Create("PasswordReset")); } return (manager); } } 

Dans votre démarrage Owin, vous allez enregistrer le rappel:

 // IAppBuilder app app.CreatePerOwinContext(ApplicationDatabaseContext.Create); app.CreatePerOwinContext(ApplicationUserManager.Create); 

qui appellera la méthode statique:

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

et

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

Vous pouvez désormais accéder au contexte de votre firebase database et au gestionnaire d’utilisateurs de manière simple et directe:

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

Dans votre ApiController (si vous utilisez WebApi):

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

Quel est le but réel de la méthode? Dans quel cas devrait-il être appliqué?

Pour répondre plus directement à votre question, cela est inutile.

  1. C’est une sorte d’usine d’IoC, que certains aiment utiliser.
  2. Celui-ci vous fait utiliser le leur (IoC) par rapport à votre choix.
  3. (Je n’aime pas l’IoC, c’est comme un anti-modèle pour les personnes qui veulent se sentir au chaud et utiliser le terme “architecture”.)
  4. Mais sérieusement, ce schéma n’intervient pas dans les interfaces IoC, c’est-à-dire les fonctions d’usine statique de l’IoC! Qui était l’idée? Pourquoi ne pas simplement utiliser la fonction Factory vous-même? Maintenant, vous devez vous rappeler (Google) un appel API supplémentaire, et lorsque vous appuyez sur F12 dans Get , cela ne vous aide plus.

Que devriez-vous faire à la place alors?

Personnellement, je suis fan d’utiliser OO pour cela, souvenez-vous de OO? La ferme Pepperidge se souvient. Avec OO, vous gardez le contrôle, vous pouvez déboguer, vous connecter et vous pouvez étendre.

 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(); } } } 

Tout cela pourrait être une perte de temps, si quelqu’un trouve des documents expliquant pourquoi les ingénieurs de Microsoft ont mis cela, ils pourraient avoir une bonne raison, mais j’en doute, alors relançons cette réponse entre-temps.

METTRE À JOUR

Voici pourquoi, il est là pour Microsoft: https://blogs.msdn.microsoft.com/webdev/2014/02/12/per-request-lifetime-management-for-usermanager-class-in-asp-net- identité/

Fondamentalement, le UserManager et tous sont construits pour ce type de structure. Les contrôles de sécurité ont lieu dans le pipeline, alors pourquoi ne pas avoir un singleton lié à la demande, pour réduire le gaspillage? Parce que c’est caché

Je recommanderais quand même de créer votre propre instance du contexte de firebase database sur une classe de base, cela le rend beaucoup plus propre à utiliser. Si vous voulez vraiment, vous pouvez avoir une propriété dans votre classe de base qui récupère le singleton de OwinContext.

Combien de temps gaspillons-nous à essayer de mettre au point ces API fantaisistes, et à atsortingbuer des atsortingbuts, etc., lorsque nous voulons simplement:

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

Clairement, je préfère le code verbeux que vous pouvez voir.

vous pouvez utiliser typeof pour obtenir le nom comme ceci:

 HttpContext.GetOwinContext().Get(typeof(ApplicationDbContext).ToSsortingng());