asp.net Identity 2.0 unity ไม่สามารถแก้ไขร้านค้าผู้ใช้เริ่มต้นได้

ฉันได้รับข้อยกเว้นต่อไปนี้เมื่อพยายามกำหนดค่า Unity โดยใช้ Unity.Mvc5 ด้วยแอปพลิเคชัน MVC 5 โดยใช้ Identity 2.0 และ Identity 2.0 Samples สำเร็จรูป ฉันได้อ่าน SO กำหนดค่า Unity DI สำหรับ ASP.NET Identity และ ฉันยังไม่ชัดเจนว่าฉันขาดอะไรไป ฉันทำอะไรผิดที่นี่?

ประเภทปัจจุบัน System.Data.Common.DbConnection เป็นคลาสนามธรรมและไม่สามารถสร้างได้ คุณขาดการแมปประเภทหรือไม่?

[ResolutionFailedException: ความละเอียดของการขึ้นต่อกันล้มเหลว พิมพ์ = "myApp.Web.Controllers.AccountController" ชื่อ = "(ไม่มี)" มีข้อยกเว้นเกิดขึ้นขณะ: ขณะกำลังแก้ไข

ข้อยกเว้นคือ: InvalidOperationException - ประเภทปัจจุบัน System.Data.Common.DbConnection เป็นคลาสนามธรรมและไม่สามารถสร้างได้ คุณขาดการแมปประเภทหรือไม่?

ในช่วงเวลาของข้อยกเว้น คอนเทนเนอร์คือ:

การแก้ไข myApp.Web.Controllers.AccountController, (ไม่มี) การแก้ไขพารามิเตอร์ "userManager" ของ Constructor myApp.Web.Controllers.AccountController (myApp.Web.Models.ApplicationUserManager userManager) การแก้ไข myApp.Web.Models.ApplicationUserManager (ไม่มี) การแก้ไขพารามิเตอร์ "ร้านค้า" ของตัวสร้าง myApp.Web.Models.ApplicationUserManager(Microsoft.AspNet.Identity.IUserStore1[[myApp.Web.DAL.Profiles.ApplicationUser, myApp.Web, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] store) Resolving Microsoft.AspNet.Identity.EntityFramework.UserStore1[myApp.Web.DAL.Profiles.ApplicationUser],(ไม่มี) (แมปจาก Microsoft.AspNet.Identity.IUserStore1[myApp.Web.DAL.Profiles.ApplicationUser], (none)) Resolving parameter "context" of constructor Microsoft.AspNet.Identity.EntityFramework.UserStore1[[myApp.Web .DAL.Profiles.ApplicationUser, myApp.Web, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]](System.Data.Entity.DbContext context) การแก้ไข System.Data.Entity.DbContext, (none) การแก้ไขพารามิเตอร์ "การเชื่อมต่อที่มีอยู่" ของตัวสร้าง System.Data.Entity.DbContext (System.Data.Common.DbConnection existingConnection, System.Data.Entity.Infrastructure.DbCompiledModel model, System.Boolean contextOwnsConnection) การแก้ไข System.Data.Common.DbConnection, (ไม่มี)

ผู้ควบคุมบัญชีตามที่ฉันได้แก้ไขแล้ว

 public AccountController(ApplicationUserManager userManager)
 {
      _userManager = userManager;
 }

 private ApplicationUserManager _userManager;

คอนเทนเนอร์ที่ฉันลงทะเบียนไว้

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



คำตอบ (2)


ฉันเห็นว่าคุณพบวิธีแก้ปัญหา แต่ฉันคิดว่าฉันมีวิธีที่ง่ายกว่า

คุณใช้ Entity Framework ใช่ไหม? ดังนั้น แอปพลิเคชันของคุณเกือบจะมีบางอย่างที่สืบทอดมาจาก DbContext อย่างแน่นอน (อาจจะสืบทอดมาจาก IdentityContext<TUser> ซึ่งจะสืบทอดมาจาก DbContext ในกรณีนี้) ในเทมเพลตเริ่มต้นคือ ApplicationDbContext

ในรูทการเรียบเรียงของคุณคุณสามารถเพิ่ม container.RegisterType<DbContext, ApplicationDbContext>(new HierarchicalLifetimeManager()); (แก้ไขได้อย่างชัดเจนหากคุณไม่ได้เรียกว่า ApplicationDbContext)

person Casey    schedule 23.04.2014
comment
ฉันจะลองดู สิ่งนี้จะง่ายกว่าการสร้าง userstore แบบกำหนดเองอย่างแน่นอนเมื่อฉันไม่ได้ทำอะไรที่แตกต่างออกไป - person Michael; 23.04.2014
comment
ใช่แล้ว ฉันค่อนข้างแน่ใจว่าจากข้อความดังกล่าว ไม่สามารถแก้ไข DbContext ซึ่งคลาสเช่น UserManager ต้องการสำเนา คุณสามารถใช้InjectionFactoryได้หากคุณมีความโน้มเอียงมาก - person Casey; 23.04.2014
comment
จะดีกว่าไหมถ้าใช้ PerRequestLifetimeManager แทน HierarchicalLifetimeManager ? - person Dragouf; 03.05.2014
comment
ใช่ อาจเป็นไปได้หากคุณติดตั้งไว้ในโปรเจ็กต์ของคุณ ฉันยึดติดกับสิ่งที่อยู่ในตัวอย่าง ฉันเชื่อว่าเป็นไปได้ที่จะทำสิ่งที่คล้ายกับ HLM และคอนเทนเนอร์ย่อย - person Casey; 04.05.2014
comment
จะเกิดอะไรขึ้นถ้าฉันมี 2 DbContexts อันหนึ่งสำหรับเรื่อง Identity เรียกว่า IdentityDb และอีกอันสำหรับองค์กรธุรกิจ BusinessDb - person Bogac; 24.08.2014
comment
@Bogac คุณมีสองทางเลือก - คุณสามารถระบุในคลาสของคุณว่าอันไหนที่คุณกำลังมองหาและลงทะเบียนทั้งเป็นประเภทจริงหรือคุณสามารถลงทะเบียน DbContext สองเวอร์ชันด้วยคีย์สตริงที่แตกต่างกัน จากนั้นระบุในการกำหนดค่า Unity ของคุณซึ่ง สิ่งที่คุณต้องการ หากนั่นไม่ตอบคำถามของคุณ ฉันขอแนะนำให้โพสต์คำถามแยกต่างหากพร้อมรายละเอียดเพิ่มเติมเกี่ยวกับสิ่งที่คุณกำลังทำ เนื่องจากความคิดเห็นไม่ใช่รูปแบบที่เหมาะสมที่สุดในการเข้าสู่ประเด็นหลัก - person Casey; 25.08.2014
comment
ฉันกำลังพยายามเพิ่ม DI ให้กับบริบทเอนทิตีของฉันและมีบรรทัดต่อไปนี้ใน UnityConfig.cs container.RegisterType<DbContext, EntitiesDataContext>(new HierarchicalLifetimeManager()); ของฉัน แต่ฉันยังคงได้รับข้อผิดพลาดที่กล่าวถึงที่นี่ มีความคิดอะไรบ้าง? :-/ - person Felipe Correa; 24.08.2015
comment
@Casey คุณช่วยดูความคิดเห็นด้านบนได้ไหม ฉันลืมพูดถึงคุณเมื่อฉันถามไปสักพักแล้ว ขอบคุณ! - person Felipe Correa; 24.08.2015
comment
@FelipeCorrea คุณสามารถได้รับข้อผิดพลาดเดียวกันนี้สำหรับส่วนประกอบใด ๆ บางทีคุณควรโพสต์คำถามของคุณเองพร้อมการติดตามสแต็กแบบเต็ม - person Casey; 25.08.2015
comment
@Casey ฉันแก้ไขมันแล้ว EntitiesDataContext ของฉันมีคอนสตรัคเตอร์หลายตัว และฉันไม่รู้ว่า Unity เลือกคอนสตรัคเตอร์ที่มีพารามิเตอร์มากกว่านี้ตามค่าเริ่มต้น ฉันต้องเรียกมันแบบนี้เพื่อแก้ไข: container.RegisterType<DbContext, EntitiesDataContext>(new PerRequestLifetimeManager(), new InjectionConstructor()); InjectionConstructor สร้างความแตกต่าง :) - person Felipe Correa; 25.08.2015

โอเค ฉันคิดออกแล้ว ฉันคิดว่า. ฉันสร้างคลาส userstore ของตัวเองแล้วเสียบปลั๊ก สิ่งนี้มีประโยชน์บ้าง http://odetocode.com/blogs/scott/archive/2014/01/20/implementing-asp-net-identity.aspx

การกำหนดค่าความสามัคคี

container.RegisterType<ApplicationDbContext>(new HierarchicalLifetimeManager());
container.RegisterType<IUserStore<ApplicationUser>, bcUserStore>(new HierarchicalLifetimeManager());

ผู้จัดการผู้ใช้

public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
{
   var manager = new ApplicationUserManager(new bcUserStore(context.Get<ApplicationDbContext>()));
// other code that's not relevant
}

ร้านค้าผู้ใช้

public class bcUserStore : IUserStore<ApplicationUser>
{
    private IDbSet<ApplicationUser> _users;
    private ApplicationDbContext _context;
    public bcUserStore(ApplicationDbContext context)
    {
        _users = context.Users;
        _context = context;
    }
    public System.Threading.Tasks.Task CreateAsync(ApplicationUser user)
    {
        user.Id = Guid.NewGuid().ToString();
        _users.Add(user);
        return _context.SaveChangesAsync();
    }

    public System.Threading.Tasks.Task DeleteAsync(ApplicationUser user)
    {
        _users.Remove(user);
        return _context.SaveChangesAsync();
    }

    public System.Threading.Tasks.Task<ApplicationUser> FindByIdAsync(string userId)
    {
        return _users.FirstOrDefaultAsync(x => x.Id == userId);
    }

    public System.Threading.Tasks.Task<ApplicationUser> FindByNameAsync(string userName)
    {
        return _users.FirstOrDefaultAsync(x => x.UserName == userName);
    }

    public System.Threading.Tasks.Task UpdateAsync(ApplicationUser user)
    {
        var current = _users.Find(user.Id);
        _context.Entry<ApplicationUser>(current).CurrentValues.SetValues(user);
        return _context.SaveChangesAsync();
    }

    public void Dispose()
    {
        _users = null;
        _context.Dispose();
    }
}
person Michael    schedule 22.04.2014