5

konstruiert werden kann, wenn ich zu http://localhost:58472/Account/Register surfen Ich habe diese AusnahmeDie aktuellen Typen, IUserStore <ApplicationUser> und DbConnection, jeweils eine Schnittstelle und abstrakte Klasse und nicht

System.InvalidOperationException: Stromart, IUserStore<ApplicationUser>, ist eine Schnittstelle und kann nicht konstruiert werden. Vermissen Sie ein Typ-Mapping?

Hier ist mein Code:

public class ApplicationUserManager : UserManager<ApplicationUser> 
{ 
    public ApplicationUserManager(IUserStore<ApplicationUser> store) 
     : base(store) 
    { } 

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

     // other code 
     return manager; 
    } 
} 

und hier ist der Code in die Steuerung:

[Authorize] 
public class AccountController : Controller 
{ 
    private ApplicationSignInManager _signInManager; 
    private ApplicationUserManager _userManager; 

    public AccountController() 
    { 
    } 

    public AccountController(
     ApplicationUserManager userManager, 
     ApplicationSignInManager signInManager) 
    { 
     UserManager = userManager; 
     SignInManager = signInManager; 
    } 

    public ApplicationSignInManager SignInManager 
    { 
     get 
     { 
      return _signInManager ?? 
       HttpContext.GetOwinContext().Get<ApplicationSignInManager>(); 
     } 
     private set 
     { 
      _signInManager = value; 
     } 
    } 

    public ApplicationUserManager UserManager 
    { 
     get 
     { 
      return _userManager ?? 
       HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>(); 
     } 
     private set 
     { 
      _userManager = value; 
     } 
    } 

    [HttpGet] 
    [AllowAnonymous] 
    public ActionResult Login(string returnUrl) 
    { 
     ViewBag.ReturnUrl = returnUrl; 
     return View(); 
    } 
} 

Sie können also sehen, wenn Sie meinen Code zu lesen, ich habe nichts geändert der ursprüngliche Code, wenn Sie ein neues MVC-Projekt erstellen, aber ich habe den obigen Fehler. Was habe ich falsch gemacht?

Ich habe einen neuen Controller namens ProfileController mit dem gleichen Code wie in meinem zweiten Codeblock aber ohne die ApplicationSignInManager gemacht, weil ich das nicht brauche.

Ich verwende auch einen Unity-Container, um die Dienste zu registrieren und zu verwalten. Hier ist der Code:

public static class UnityConfig 
{ 
    public static void RegisterComponents() 
    { 
     var container = new UnityContainer(); 

     container.RegisterType<IGenericRepo<Category>, GenericRepo<Category>>(); 
     container.RegisterType<ICategoryService, CategoryService>(); 
     //container.RegisterType<IUser, ApplicationUser>(); 

     DependencyResolver.SetResolver(new UnityDependencyResolver(container)); 
    } 
} 

Wenn ich die Zeile in Code oben auskommentieren, gibt es keinen Unterschied, wenn ich die Website ausführen.


Update:

durch einen Kommentar von @Jay ich diesen Code in der Unity-Manager hinzugefügt haben.

System.InvalidOperationException:

container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(); 

Jetzt habe ich diese Ausnahme bekam Stromart, System.Data.Common.DbConnection, eine abstrakte Klasse und nicht konstruiert werden kann. Vermissen Sie ein Typ-Mapping?

Hier sind einige Informationen aus dem Stack-Trace:

  1. InvalidOperationException

    ist ein Fehler aufgetreten ist, wenn eine Steuerung des Typs AccountController zu schaffen versuchen. Stellen Sie sicher, dass der Controller über einen parameterlosen öffentlichen Konstruktor verfügt.

    Ja, ich habe einen parameterlosen öffentlichen Konstruktor.

  2. ResolutionFailedException

    Auflösung der Abhängigkeit ist fehlgeschlagen, type = "AccountController", name = "(none)".

    container.RegisterType<IDbConnection, DbConnection>(); 
    

    Aber ich habe immer noch die gleiche Ausnahme:

Also habe ich diese Zeile in dem Manager Unity hinzugefügt.

Stromart, System.Data.Common.DbConnection ...


Update:

durch einen Kommentar von @RandyLevy ich das versucht habe, mit dieser Frage zu helfen Configure Unity DI for ASP.NET Identity:

  1. Addiert man diese zu den AccountController:

    // two fields added 
    private readonly UserManager<ApplicationUser> _userManager; 
    private readonly RoleManager<IdentityRole> _roleManager; 
    
    // constructor added 
    public AccountController(
        IUserStore<ApplicationUser> userStore, 
        IRoleStore<IdentityRole> roleStore, 
        ApplicationSignInManager signInManager) 
    { 
        _userManager = new UserManager<ApplicationUser>(userStore); 
        _roleManager = new RoleManager<IdentityRole>(roleStore); 
        SignInManager = signInManager; // I need this 
    } 
    
    public ApplicationSignInManager SignInManager // I need this 
    { 
        get 
        { 
         return _signInManager ?? 
          HttpContext.GetOwinContext().Get<ApplicationSignInManager>(); 
        } 
        private set 
        { 
         _signInManager = value; 
        } 
    } 
    
    public UserManager<ApplicationUser> UserManager // replace by other property 
                   // type of ApplicationUserManager 
    { 
        get 
        { 
         return _userManager ?? 
          HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>(); 
        } 
        //private set // comment this because _usermanager is readonly. 
        //{ 
        // _userManager = value; 
        //} 
    } 
    
    //public ApplicationUserManager UserManager // replaced by the property type of 
    //           // UserManager<ApplicationUser> 
    //{ 
    // get 
    // { 
    //  return _userManager ?? 
    //   HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>(); 
    // } 
    // private set 
    // { 
    //  _userManager = value; 
    // } 
    //} 
    
  2. Addiert man diese in UnityManager:

    InjectionConstructor accountInjectionConstructor = 
        new InjectionConstructor(new ApplicationDbContext()); 
    
    container.RegisterType<AccountController>(); 
    container.RegisterType<IController, Controller>(); 
    
    container.RegisterType 
        <IRoleStore<IdentityRole>, RoleStore<IdentityRole>> 
        (accountInjectionConstructor); // on this line 
    
    container.RegisterType 
        <IUserStore<ApplicationUser>, UserStore<ApplicationUser>> 
        (accountInjectionConstructor); 
    

Aber ich habe diesen Fehler habe (keine Laufzeit Ausnahme) auf der Linie mit dem Kommentar:

der Typ RoleStore<IdentityRole> kann nicht als Typ-Parameter in TTo gattungs oder Meth verwendet werden od unten:

UnityContainerExtensions.RegisterType<TFrom, TTo> 
    (IUnityContainer, params InjectionMember[]) 

Es gibt keine implizite Referenz Umwandlung von RoleStore<IdentityRole> zu IRoleStore<IdentityRole>.

+2

fehlt Ihnen ein Registertyp für IUserStore ? – Jay

+1

https://stackoverflow.com/questions/21927785/configure-unity-di-for-asp-net-identity kann helfen. –

+0

@Jay: Danke, für den Hinweis, aber ich habe jetzt eine andere Ausnahme. Mehr Informationen in meiner Frage. –

Antwort

13

Endlich habe ich eine Lösung für mein Problem gefunden. Ich habe diesen Code dem Unity Manager hinzugefügt.

container.RegisterType<DbContext, ApplicationDbContext>(new HierarchicalLifetimeManager()); 
container.RegisterType<UserManager<ApplicationUser>>(new HierarchicalLifetimeManager()); 
container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(new HierarchicalLifetimeManager()); 
container.RegisterType<AccountController>(new InjectionConstructor()); 
+1

Ich habe erst den Fehler bekommen, den das OP bekommen hat, nachdem ich Unity installiert habe. Scheint etwas mit dem Abhängigkeits-Resolver von Unity zu tun zu haben, der nicht mit der nativen Identitätsfunktion arbeitet. Die Registrierung dieser Typen hat es behoben. – JARRRRG

2

Update für H. Pauwelyn beantworten. Das ursprüngliche Problem dafür ist, dass Unity versucht, den Konstruktor mit zwei Parametern aufzurufen.

Die folgende Zeile sagt Unity, dass sie stattdessen den parameterlosen Konstruktor aufrufen soll und nichts anderes benötigt. Das hat für mich funktioniert.

container.RegisterType<AccountController>(new InjectionConstructor());