0

projet actuel:Impossible d'employer AutoFac correctement dans un cadre référentiel en utilisant l'boilerplate ASP.NET MVC HTML5

J'ai fait de mon mieux pour suivre le modèle de référentiel dans l'article I lié à ci-dessus, comme je l'ai a distinct need for a repository pattern, ainsi que le désir de voir les ID utilisateur en tant que GUID et pas seulement en tant que chaînes nvarchar (128). Essentiellement, j'ai besoin de partager des structures de table sur plusieurs sites, j'ai donc utilisé un modèle de référentiel qui m'a également permis de partager des connexions sur ces multiples sites. Les différents sites utilisent le modèle ASP.NET MVC HTML5 Boilerplate, AutoFac y est donc intégré. Cependant, veuillez également noter que j'ai des difficultés conceptuelles considérables avec Dependency Injection en général, semblable à essayer de sentir la couleur bleue, ou d'essayer de goûter la saveur de la température. Je ne suis pas en train de le faire.

J'ai également réussi à étendre ce modèle de référentiel pour me permettre d'activer les migrations. Comme dans: Je suis en mesure de pousser une migration du modèle de base de données vers la base de données. Malheureusement, parce que j'ai affaire à la couche Infrastructure (j'ai appelé mes couches de structure de référentiel Core pour le modèle DB et Infrastructure pour tout le reste), je ne peux pas injecter un administrateur principal dans la base de données. Couche d'infrastructure. En tant que tel, je ne peux pas utiliser ApplicationDbInitializer dans les infrastructures:

namespace Company.Infrastructure.Context { 
    using Identity; 
    using Microsoft.AspNet.Identity; 
    using System; 
    using Store; 
    using System.Data.Entity; 

    public class ApplicationDbInitializer : DropCreateDatabaseAlways<ApplicationDbContext> { 
    private readonly UserManager<IdentityUser, Guid> _userManager; 
    private readonly RoleManager<IdentityRole, Guid> _roleManager; 

    public ApplicationDbInitializer() { } 

    public ApplicationDbInitializer(UserManager<IdentityUser, Guid> userManager, RoleManager<IdentityRole, Guid> roleManager) { 
     _userManager = userManager; 
     _roleManager = roleManager; 
    } 

    // This example shows you how to create a new database if the Model changes 
    //public class ApplicationDbInitializer : DropCreateDatabaseIfModelChanges<ApplicationDbContext> 
    protected override void Seed(ApplicationDbContext context) { 
     InitializeIdentityForEf(context); 
     base.Seed(context); 
    } 

    //Create [email protected] with [email protected] in the Admin role   
    public void InitializeIdentityForEf(ApplicationDbContext db) { 
     const string username = "CompanyName"; 
     const string email = "[email protected]"; 
     const string password = "password"; 
     const string roleName = "Administrator"; 

     //Create Role Admin if it does not exist 
     var role = _roleManager.FindByName(roleName); 
     if(role == null) { 
     role = new IdentityRole(roleName); 
     var roleresult = _roleManager.Create(role); 
     } 

     var user = _userManager.FindByName(username); 
     if(user == null) { 
     user = new IdentityUser { UserName = username, Email = email }; 
     var result = _userManager.Create(user, password); 
     result = _userManager.SetLockoutEnabled(user.Id, false); 
     } 

     // Add user admin to Role Admin if not already added 
     var rolesForUser = _userManager.GetRoles(user.Id); 
     if(!rolesForUser.Contains(role.Name)) { 
     var result = _userManager.AddToRole(user.Id, role.Name); 
     } 
    } 
    } 
} 

pour injecter l'administrateur principal.

En tant que tel, je tente d'injecter un utilisateur d'administrateur principal par l'un des sites Web, mais lorsque je tente d'enregistrer modifié UserManager et UserStore il semble que AutoFac ne peut pas revenir sur ces enregistrements, même si elle prend le tous les autres enregistrements fournis avec le modèle vont très bien.

AutoFac est enregistré par App_Start\Startup.Container.cs:

namespace Company.Website { 
    using System.Reflection; 
    using System.Web.Mvc; 
    using Autofac; 
    using Autofac.Integration.Mvc; 
    using Services; 
    using Owin; 
    using System; 
    using Microsoft.AspNet.Identity; 
    using Infrastructure.Identity; 
    using Infrastructure.Store; 
    using Core.Repositories; 
    using Infrastructure.Context; 

    /// <summary> 
    /// Register types into the Autofac Inversion of Control (IOC) container. Autofac makes it easy to register common 
    /// MVC types like the <see cref="UrlHelper"/> using the <see cref="AutofacWebTypesModule"/>. Feel free to change 
    /// this to another IoC container of your choice but ensure that common MVC types like <see cref="UrlHelper"/> are 
    /// registered. See http://autofac.readthedocs.org/en/latest/integration/aspnet.html. 
    /// </summary> 
    public partial class Startup { 
    public static void ConfigureContainer(IAppBuilder app) { 
     var container = CreateContainer(); 
     app.UseAutofacMiddleware(container); 

     // Register MVC Types 
     app.UseAutofacMvc(); 
    } 

    private static IContainer CreateContainer() { 
     var builder = new ContainerBuilder(); 
     var assembly = Assembly.GetExecutingAssembly(); 
     RegisterServices(builder); 
     RegisterMvc(builder, assembly); 
     var container = builder.Build(); 
     SetMvcDependencyResolver(container); 
     return container; 
    } 

    private static void RegisterServices(ContainerBuilder builder) { 
     builder.RegisterType<BrowserConfigService>().As<IBrowserConfigService>().InstancePerRequest(); 
     builder.RegisterType<CacheService>().As<ICacheService>().SingleInstance(); 
     builder.RegisterType<FeedService>().As<IFeedService>().InstancePerRequest(); 
     builder.RegisterType<LoggingService>().As<ILoggingService>().SingleInstance(); 
     builder.RegisterType<ManifestService>().As<IManifestService>().InstancePerRequest(); 
     builder.RegisterType<OpenSearchService>().As<IOpenSearchService>().InstancePerRequest(); 
     builder.RegisterType<RobotsService>().As<IRobotsService>().InstancePerRequest(); 
     builder.RegisterType<SitemapService>().As<ISitemapService>().InstancePerRequest(); 
     builder.RegisterType<SitemapPingerService>().As<ISitemapPingerService>().InstancePerRequest(); 

     // My additions: 
     builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerRequest(); 
     builder.RegisterType<UserManager<IdentityUser, Guid>>().As<UserManager<IdentityUser, Guid>>().InstancePerRequest(); 
     builder.RegisterType<UserStore>().As<IUserStore<IdentityUser, Guid>>().InstancePerLifetimeScope(); 
    } 

    private static void RegisterMvc(ContainerBuilder builder, Assembly assembly) { 
     // Register Common MVC Types 
     builder.RegisterModule<AutofacWebTypesModule>(); 

     // Register MVC Filters 
     builder.RegisterFilterProvider(); 

     // Register MVC Controllers 
     builder.RegisterControllers(assembly); 
    } 

    /// <summary> 
    /// Sets the ASP.NET MVC dependency resolver. 
    /// </summary> 
    /// <param name="container">The container.</param> 
    private static void SetMvcDependencyResolver(IContainer container) { 
     DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); 
    } 
    } 
} 

Et le à partir de mon contrôleur Home est en tant que tel:

namespace Company.Website.Controllers { 
    using Boilerplate.Web.Mvc; 
    using Boilerplate.Web.Mvc.Filters; 
    using Constants; 
    using Identity; 
    using Infrastructure.Models; 
    using Infrastructure.Context; 
    using Infrastructure.Store; 
    using Microsoft.AspNet.Identity; 
    using Microsoft.Owin.Security; 
    using Recaptcha.Web; 
    using Recaptcha.Web.Mvc; 
    using Services; 
    using System; 
    using System.Diagnostics; 
    using System.Linq; 
    using System.Net; 
    using System.Text; 
    using System.Threading; 
    using System.Threading.Tasks; 
    using System.Web.Mvc; 


    public class HomeController : Controller { 
    private readonly IBrowserConfigService _browserConfigService; 
    private readonly IFeedService _feedService; 
    private readonly IManifestService _manifestService; 
    private readonly IOpenSearchService _openSearchService; 
    private readonly IRobotsService _robotsService; 
    private readonly ISitemapService _sitemapService; 
    private ApplicationDbContext _db; 
    private readonly UserManager<IdentityUser, Guid> _userManager; 

    public HomeController(
     IBrowserConfigService browserConfigService, 
     IFeedService feedService, 
     IManifestService manifestService, 
     IOpenSearchService openSearchService, 
     IRobotsService robotsService, 
     ISitemapService sitemapService, 
     UserManager<IdentityUser, Guid> userManager) { 
     _browserConfigService = browserConfigService; 
     _feedService = feedService; 
     _manifestService = manifestService; 
     _openSearchService = openSearchService; 
     _robotsService = robotsService; 
     _sitemapService = sitemapService; 
     _userManager = userManager; 
    } 

Le point entier est que j'ai l'intention d'utiliser la première exécution de la méthode Index pour injecter un utilisateur administrateur dans la base de données:

var user = _userManager.FindByName(username); 
if(user == null) { 
    user = new IdentityUser { UserName = username, Email = email }; 
    var result = _userManager.Create(user, password); 
    result = _userManager.SetLockoutEnabled(user.Id, false); 
} 

Cela aurait pu être fait à partir de n'importe quelle page, je viens de choisir Index. Une fois qu'un utilisateur admin a été injecté, le code serait déclassé et supprimé, parce que ... eh bien, le travail est fait à ce moment-là. Utilisateur administrateur créé.

Le problème est que tout le système s'effondre avec la présence des entrées UserManager dans le constructeur par défaut. Tout va en pot:

Autofac.Core.DependencyResolutionException: Aucun des constructeurs trouvés avec 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder 'sur le type' Company.Website.Controllers.HomeController 'peut être appelé avec les services et les paramètres disponibles: Impossible de résoudre le paramètre' Microsoft.AspNet.Identity.UserManager 2[Company.Website.Identity.IdentityUser,System.Guid] userManager' of constructor 'Void .ctor(Company.Website.Services.IBrowserConfigService, Company.Website.Services.IFeedService, Company.Website.Services.IManifestService, Company.Website.Services.IOpenSearchService, Company.Website.Services.IRobotsService, Company.Website.Services.ISitemapService, Microsoft.AspNet.Identity.UserManager 2 [Company.Website.Identity.IdentityUser, System.Guid]) '.

Retirez cette entrée du constructeur par défaut, tout va bien (avec le code de création d'utilisateur Index commenté, bien sûr). Remettez-le en place, et l'attaque de panique DotNet extraordinaire.

Je me bats la tête depuis un certain temps et je suis à bout de nerfs. Toute aide serait grandement appréciée. J'ai found other posts that are similar, mais ils n'ont pas abouti à une résolution pour moi.


Edit 1: Une demande de UserStore.cs, se trouve sous Company.Infrastructure.Store:

namespace Company.Infrastructure.Store { 
    using Identity; 
    using Core.Repositories; 
    using Core.Models; 
    using Microsoft.AspNet.Identity; 
    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Security.Claims; 
    using System.Threading.Tasks; 
    using Context; 

    public class UserStore : IUserStore<IdentityUser, Guid>, IUserLoginStore<IdentityUser, Guid>, IUserClaimStore<IdentityUser, Guid>, IUserRoleStore<IdentityUser, Guid>, IUserPasswordStore<IdentityUser, Guid>, IUserSecurityStampStore<IdentityUser, Guid>, IDisposable { 
    private readonly IUnitOfWork _unitOfWork; 

    public UserStore(IUnitOfWork unitOfWork) { 
     _unitOfWork = unitOfWork; 
    } 

    #region IUserStore<IdentityUser, Guid> Members 
    public Task CreateAsync(IdentityUser user) { 
     if(user == null) throw new ArgumentNullException(nameof(user)); 
     var u = getUser(user); 
     _unitOfWork.UserRepository.Add(u); 
     return _unitOfWork.SaveChangesAsync(); 
    } 

    public Task DeleteAsync(IdentityUser user) { 
     if(user == null) throw new ArgumentNullException(nameof(user)); 
     var u = getUser(user); 
     _unitOfWork.UserRepository.Remove(u); 
     return _unitOfWork.SaveChangesAsync(); 
    } 

    public Task<IdentityUser> FindByIdAsync(Guid userId) { 
     var user = _unitOfWork.UserRepository.FindById(userId); 
     return Task.FromResult(getIdentityUser(user)); 
    } 

    public Task<IdentityUser> FindByNameAsync(string userName) { 
     var user = _unitOfWork.UserRepository.FindByUserName(userName); 
     return Task.FromResult(getIdentityUser(user)); 
    } 

    public Task UpdateAsync(IdentityUser user) { 
     if(user == null) throw new ArgumentException("user"); 
     var u = _unitOfWork.UserRepository.FindById(user.Id); 
     if(u == null) throw new ArgumentException("IdentityUser does not correspond to a User entity.", nameof(user)); 
     PopulateUser(u, user); 
     _unitOfWork.UserRepository.Update(u); 
     return _unitOfWork.SaveChangesAsync(); 
    } 
    #endregion 

    #region IDisposable Members 
    public void Dispose() { 
     // Dispose does nothing since we want Unity to manage the lifecycle of our Unit of Work 
    } 
    #endregion 

    #region IUserClaimStore<IdentityUser, Guid> Members 
    public Task AddClaimAsync(IdentityUser user, Claim claim) { 
     if(user == null) throw new ArgumentNullException(nameof(user)); 
     if(claim == null) throw new ArgumentNullException(nameof(claim)); 

     var u = _unitOfWork.UserRepository.FindById(user.Id); 
     if(u == null) throw new ArgumentException("IdentityUser does not correspond to a User entity.", nameof(user)); 

     var c = new UserClaim { 
     ClaimType = claim.Type, 
     ClaimValue = claim.Value, 
     User = u 
     }; 
     u.UserClaim.Add(c); 

     _unitOfWork.UserRepository.Update(u); 
     return _unitOfWork.SaveChangesAsync(); 
    } 

    public Task<IList<Claim>> GetClaimsAsync(IdentityUser user) { 
     if(user == null) throw new ArgumentNullException(nameof(user)); 

     var u = _unitOfWork.UserRepository.FindById(user.Id); 
     if(u == null) throw new ArgumentException("IdentityUser does not correspond to a User entity.", nameof(user)); 

     return Task.FromResult<IList<Claim>>(u.UserClaim.Select(x => new Claim(x.ClaimType, x.ClaimValue)).ToList()); 
    } 

    public Task RemoveClaimAsync(IdentityUser user, Claim claim) { 
     if(user == null) throw new ArgumentNullException(nameof(user)); 
     if(claim == null) throw new ArgumentNullException(nameof(claim)); 

     var u = _unitOfWork.UserRepository.FindById(user.Id); 
     if(u == null) throw new ArgumentException("IdentityUser does not correspond to a User entity.", nameof(user)); 

     var c = u.UserClaim.FirstOrDefault(x => x.ClaimType == claim.Type && x.ClaimValue == claim.Value); 
     u.UserClaim.Remove(c); 

     _unitOfWork.UserRepository.Update(u); 
     return _unitOfWork.SaveChangesAsync(); 
    } 
    #endregion 

    #region IUserLoginStore<IdentityUser, Guid> Members 
    public Task AddLoginAsync(IdentityUser user, UserLoginInfo login) { 
     if(user == null) throw new ArgumentNullException(nameof(user)); 
     if(login == null) throw new ArgumentNullException(nameof(login)); 

     var u = _unitOfWork.UserRepository.FindById(user.Id); 
     if(u == null) throw new ArgumentException("IdentityUser does not correspond to a User entity.", nameof(user)); 

     var l = new UserLogin { 
     LoginProvider = login.LoginProvider, 
     ProviderKey = login.ProviderKey, 
     User = u 
     }; 
     u.UserLogin.Add(l); 

     _unitOfWork.UserRepository.Update(u); 
     return _unitOfWork.SaveChangesAsync(); 
    } 

    public Task<IdentityUser> FindAsync(UserLoginInfo login) { 
     if(login == null) throw new ArgumentNullException(nameof(login)); 

     var identityUser = default(IdentityUser); 

     var l = _unitOfWork.LoginRepository.GetByProviderAndKey(login.LoginProvider, login.ProviderKey); 
     if(l != null) identityUser = getIdentityUser(l.User); 

     return Task.FromResult(identityUser); 
    } 

    public Task<IList<UserLoginInfo>> GetLoginsAsync(IdentityUser user) { 
     if(user == null) throw new ArgumentNullException(nameof(user)); 

     var u = _unitOfWork.UserRepository.FindById(user.Id); 
     if(u == null) throw new ArgumentException("IdentityUser does not correspond to a User entity.", nameof(user)); 

     return Task.FromResult<IList<UserLoginInfo>>(u.UserLogin.Select(x => new UserLoginInfo(x.LoginProvider, x.ProviderKey)).ToList()); 
    } 

    public Task RemoveLoginAsync(IdentityUser user, UserLoginInfo login) { 
     if(user == null) throw new ArgumentNullException(nameof(user)); 
     if(login == null) throw new ArgumentNullException(nameof(login)); 

     var u = _unitOfWork.UserRepository.FindById(user.Id); 
     if(u == null) throw new ArgumentException("IdentityUser does not correspond to a User entity.", nameof(user)); 

     var l = u.UserLogin.FirstOrDefault(x => x.LoginProvider == login.LoginProvider && x.ProviderKey == login.ProviderKey); 
     u.UserLogin.Remove(l); 

     _unitOfWork.UserRepository.Update(u); 
     return _unitOfWork.SaveChangesAsync(); 
    } 
    #endregion 

    #region IUserRoleStore<IdentityUser, Guid> Members 
    public Task AddToRoleAsync(IdentityUser user, string roleName) { 
     if(user == null) throw new ArgumentNullException(nameof(user)); 
     if(string.IsNullOrWhiteSpace(roleName)) throw new ArgumentException("Argument cannot be null, empty, or whitespace: roleName."); 

     var u = _unitOfWork.UserRepository.FindById(user.Id); 
     if(u == null) throw new ArgumentException("IdentityUser does not correspond to a User entity.", nameof(user)); 
     var r = _unitOfWork.RoleRepository.FindByName(roleName); 
     if(r == null) throw new ArgumentException("roleName does not correspond to a Role entity.", nameof(roleName)); 

     u.Role.Add(r); 
     _unitOfWork.UserRepository.Update(u); 

     return _unitOfWork.SaveChangesAsync(); 
    } 

    public Task<IList<string>> GetRolesAsync(IdentityUser user) { 
     if(user == null) throw new ArgumentNullException(nameof(user)); 

     var u = _unitOfWork.UserRepository.FindById(user.Id); 
     if(u == null) throw new ArgumentException("IdentityUser does not correspond to a User entity.", nameof(user)); 

     return Task.FromResult<IList<string>>(u.Role.Select(x => x.Name).ToList()); 
    } 

    public Task<bool> IsInRoleAsync(IdentityUser user, string roleName) { 
     if(user == null) throw new ArgumentNullException(nameof(user)); 
     if(string.IsNullOrWhiteSpace(roleName)) throw new ArgumentException("Argument cannot be null, empty, or whitespace: role."); 

     var u = _unitOfWork.UserRepository.FindById(user.Id); 
     if(u == null) throw new ArgumentException("IdentityUser does not correspond to a User entity.", nameof(user)); 

     return Task.FromResult(u.Role.Any(x => x.Name == roleName)); 
    } 

    public Task RemoveFromRoleAsync(IdentityUser user, string roleName) { 
     if(user == null) throw new ArgumentNullException(nameof(user)); 
     if(string.IsNullOrWhiteSpace(roleName)) throw new ArgumentException("Argument cannot be null, empty, or whitespace: role."); 

     var u = _unitOfWork.UserRepository.FindById(user.Id); 
     if(u == null) throw new ArgumentException("IdentityUser does not correspond to a User entity.", nameof(user)); 

     var r = u.Role.FirstOrDefault(x => x.Name == roleName); 
     u.Role.Remove(r); 

     _unitOfWork.UserRepository.Update(u); 
     return _unitOfWork.SaveChangesAsync(); 
    } 
    #endregion 

    #region IUserPasswordStore<IdentityUser, Guid> Members 
    public Task<string> GetPasswordHashAsync(IdentityUser user) { 
     if(user == null) throw new ArgumentNullException(nameof(user)); 
     return Task.FromResult(user.PasswordHash); 
    } 

    public Task<bool> HasPasswordAsync(IdentityUser user) { 
     if(user == null) throw new ArgumentNullException(nameof(user)); 
     return Task.FromResult(!string.IsNullOrWhiteSpace(user.PasswordHash)); 
    } 

    public Task SetPasswordHashAsync(IdentityUser user, string passwordHash) { 
     user.PasswordHash = passwordHash; 
     return Task.FromResult(0); 
    } 
    #endregion 

    #region IUserSecurityStampStore<IdentityUser, Guid> Members 
    public Task<string> GetSecurityStampAsync(IdentityUser user) { 
     if(user == null) throw new ArgumentNullException(nameof(user)); 
     return Task.FromResult(user.SecurityStamp); 
    } 

    public Task SetSecurityStampAsync(IdentityUser user, string stamp) { 
     user.SecurityStamp = stamp; 
     return Task.FromResult(0); 
    } 
    #endregion 

    #region Private Methods 
    private User getUser(IdentityUser identityUser) { 
     if(identityUser == null) return null; 

     var user = new User(); 
     PopulateUser(user, identityUser); 

     return user; 
    } 

    private static void PopulateUser(User user, IdentityUser identityUser) { 
     user.UserId = identityUser.Id; 
     user.UserName = identityUser.UserName; 
     user.PasswordHash = identityUser.PasswordHash; 
     user.SecurityStamp = identityUser.SecurityStamp; 
    } 

    private IdentityUser getIdentityUser(User user) { 
     if(user == null) return null; 

     var identityUser = new IdentityUser(); 
     PopulateIdentityUser(identityUser, user); 

     return identityUser; 
    } 

    private static void PopulateIdentityUser(IdentityUser identityUser, User user) { 
     identityUser.Id = user.UserId; 
     identityUser.UserName = user.UserName; 
     identityUser.PasswordHash = user.PasswordHash; 
     identityUser.SecurityStamp = user.SecurityStamp; 
    } 
    #endregion 
    } 
} 
+0

Pourriez-vous publier l'implémentation de la classe 'UserStore'? J'ai l'impression que vous pourriez manquer l'enregistrement pour le 'DbContext' dont' UserStore' a besoin. –

+0

Fourni. Bien que ce soit plutôt un copier-coller du contenu de l'article Repository. –

+1

Pourriez-vous essayer de changer 'builder.RegisterType >(). Comme >(). InstancePerRequest();' à 'builder.RegisterType >() .InstancePerRequest(); '? – tdragon

Répondre

0

Merci à tdragon, j'ai pu bash ensemble assez roches au hasard pour me monter une injection de dépendance fonctionnelle. Parce que j'ai utilisé ASP.NET MVC HTML5 Boilerplate, la configuration de dépendance réelle sera probablement différente d'une configuration AutoFac par défaut, mais l'élément clé est que si vous utilisez le même repository pattern tutorial comme je l'ai fait, vous devrez créer ce qui suit dans votre StartupContainer.cs:

builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerRequest(); 
builder.RegisterType<UserManager<IdentityUser, Guid>>().InstancePerRequest(); 
builder.RegisterType<UserStore>().As<IUserStore<IdentityUser, Guid>>().InstancePerLifetimeScope(); 
builder.RegisterType<RoleManager<IdentityRole, Guid>>().InstancePerRequest(); 
builder.RegisterType<RoleStore>().As<IRoleStore<IdentityRole, Guid>>().InstancePerLifetimeScope(); 

à partir de là, quel que soit le contrôleur que vous souhaitez manipuler les utilisateurs, vous devez ajouter ce qui suit:

private readonly IUnitOfWork _unitOfWork; 
private readonly UserManager<IdentityUser, Guid> _userManager; 
private readonly RoleManager<IdentityRole, Guid> _roleManager; 

public ControllerName(
    IUnitOfWork unitOfWork, 
    UserManager<IdentityUser, Guid> userManager, 
    RoleManager<IdentityRole, Guid> roleManager) { 
    _unitOfWork = unitOfWork; 
    _userManager = userManager; 
    _roleManager = roleManager; 
} 

d'accord, mon travail avec ce modèle de référentiel est pas t complete - la table réelle User est significativement modifiée par défaut, et mon insertion d'utilisateur échoue en raison de problèmes de validation (je pense que quelque chose se déclenche sur des valeurs non nulles que je ne spécifie pas explicitement dans mon utilisateur insertion, même si les champs de base de données ont des valeurs par défaut), mais l'important est que l'injection de dépendance ne soit plus le problème.