Hola, tenemos la solución a tu interrogante, continúa leyendo y la obtendrás aquí.
Solución:
CreatePerOwinContext registra un static callback que su aplicación usará para recuperar una nueva instancia de un tipo específico.
Esta devolución de llamada se llamará una vez por solicitud y almacenará el objeto / objetos en OwinContext para que pueda utilizarlos durante toda la aplicación.
Digamos que ha definido su propia implementación de 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;
y su implementación 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);
En tu Owin Puesta en marcha registrará la devolución de llamada:
// IAppBuilder app
app.CreatePerOwinContext(ApplicationDatabaseContext.Create);
app.CreatePerOwinContext(ApplicationUserManager.Create);
que llamará al static método:
public static ApplicationDatabaseContext Create()
return new ApplicationDatabaseContext();
y
public static ApplicationUserManager Create(IdentityFactoryOptions options, IOwinContext context)
...
Ahora podrá acceder al contexto de su base de datos y al administrador de usuarios de una manera sencilla y directa:
ApplicationDatabaseContext dbContext = context.OwinContext.Get();
ApplicationUserManager userManager = context.OwinContext.GetUserManager();
En tus ApiController (si está usando WebApi):
IAuthenticationManager authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
ApplicationUserManager applicationUserManager = HttpContext.Current.GetOwinContext().GetUserManager();
¿Cuál es el verdadero propósito del método? ¿En qué caso debería aplicarse?
Para responder a su pregunta de manera más directa, esto es inútil.
- Es una especie de fábrica de IoC, que a algunas personas les gusta usar.
- Este te hace usar el de ellos (IoC) sobre tu elección.
- (No me gusta IoC, se siente como un anti-patrón para las personas que quieren sentirse cálidas y confusas y usan el término “arquitectura”).
- Pero en serio, este patrón no tiene interfaces de IoC, es IoC static funciones de fábrica! ¿De quién fue la idea? ¿Por qué no utilizar la función Factory usted mismo? Ahora debe recordar (Google) una llamada adicional a la API, y cuando presione F12 en
Get
, no te lleva a ninguna parte útil.
¿Qué deberías hacer en su lugar entonces?
Personalmente, soy fanático de usar OO para esto, ¿recuerdas OO? La granja de Pepperidge recuerda. Con OO, usted mantiene el control, puede depurar, registrar y extender.
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();
Todo esto podría ser una pérdida de tiempo, si alguien encuentra alguna documentación sobre la razón por la que los ingenieros de Microsoft pusieron esto, podría tener una buena razón por la cual, pero lo dudo, así que vamos a votar esta respuesta mientras tanto.
ACTUALIZACIÓN 1
Aquí está el por qué, por qué está ahí para Microsoft: https://blogs.msdn.microsoft.com/webdev/2014/02/12/per-request-lifetime-management-for-usermanager-class-in-asp-net- identidad/
Básicamente, el UserManager y todos ellos están diseñados para este tipo de estructura. Las comprobaciones de seguridad ocurren en la tubería, entonces, ¿por qué no tener un singleton vinculado a la solicitud, para reducir el desperdicio? Porque está escondido.
Aún así, recomendaría crear su propia instancia del contexto db en una clase base, lo hace mucho más limpio de usar. Si realmente lo desea, puede tener una propiedad en su clase base que recupere el singleton de OwinContext.
¿Cuánto tiempo perdemos tratando de desarrollar estas sofisticadas API y Authorize attributes y similares, cuando todo lo que queremos hacer es:
public void DoSomething()
DemandAuthenticated();
DemandAuthorised(typeof(somethingClass), "DoSomething");
Claramente, prefiero el código detallado que pueda ver.
Actualización 2
Los contextos de EF no deben mantenerse como singletons, y ciertamente no a través de ningún patrón de repositorio o de IoC.
Generalmente, sí, IoC puede ser bueno en situaciones. ¿Pero específicamente para un dbContext? No.
1) Los contextos EF DB son una unidad de trabajo, deben ser de corta duración. Si los mantiene en ejecución durante mucho tiempo, la caché de objetos ralentizará las consultas y las actualizaciones / inserciones en la base de datos subyacente se ralentizarán. Está diseñado para tener una vida útil corta. 2) Además, los contextos EF ya están débilmente acoplados. Puede cambiar el RDBMS detrás de un contexto en la conexión string, incluso puede usar solo memoria. 3) EF tiene LINQ, que es muy flexible, expresivo y seguro para escribir. 4) La base de datos no es un servicio de nivel empresarial para IoC, es una herramienta que utilizan los servicios para comunicarse con la base de datos. Quizás, podría tener algún tipo de servicio IEmail al que se accede a través de IoC. Pero debería acceder a la base de datos interna utilizando un nuevo contexto EF que se elimina inmediatamente después de completar las consultas. 5) Dado 1-4 arriba, ciertamente no queremos que ninguna capa de interfaz intermedia (Servicio o Repositorio) arruine todos los beneficios de usar EF en primer lugar.
puedes utilizar typeof
para obtener el nombre así:
HttpContext.GetOwinContext().Get(typeof(ApplicationDbContext).ToString());
Reseñas y valoraciones
Tienes la opción de añadir valor a nuestro contenido informacional contribuyendo tu veteranía en las explicaciones.