Единство asp.net identity 2.0 не разрешает хранилище пользователей по умолчанию

я получаю следующее исключение при попытке настроить Unity с помощью Unity.Mvc5 с приложением MVC 5 с использованием Identity 2.0 и шаблона Identity 2.0 Samples. я прочитал этот SO Настройка Unity DI для ASP.NET Identity и я до сих пор не понимаю, что мне не хватает. Что я здесь делаю неправильно?

Текущий тип System.Data.Common.DbConnection является абстрактным классом и не может быть сконструирован. Вам не хватает сопоставления типов?

[ResolutionFailedException: Ошибка разрешения зависимости, type = "myApp.Web.Controllers.AccountController", name = "(none)". Исключение произошло во время: при разрешении.

Исключение: InvalidOperationException — текущий тип System.Data.Common.DbConnection является абстрактным классом и не может быть создан. Вам не хватает сопоставления типов?

На момент исключения контейнер был:

Разрешение myApp.Web.Controllers.AccountController, (нет) Разрешение параметра "userManager" конструктора 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],(none) (сопоставлено с 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, версия = 1.0.0.0, культура = нейтральная, PublicKeyToken = null]] (контекст System.Data.Entity.DbContext) Разрешение System.Data.Entity.DbContext, (нет) Разрешающий параметр «existingConnection» конструктора System.Data.Entity.DbContext(System.Data.Common.DbConnection existsConnection, модель System.Data.Entity.Infrastructure.DbCompiledModel, 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
Я попробую. это, безусловно, было бы намного проще, чем создавать собственное хранилище пользователей, когда я не делаю ничего другого. - 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 в свой контекст Entities и иметь следующую строку в моем 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
@ Кейси, я решил это. У моего EntitiesDataContext было несколько конструкторов, и я не знал, что Unity по умолчанию выбирает конструктор с большим количеством параметров. Мне пришлось назвать это так, чтобы исправить это: container.RegisterType<DbContext, EntitiesDataContext>(new PerRequestLifetimeManager(), new InjectionConstructor()); InjectionConstructor имело значение :) - person Felipe Correa; 25.08.2015

хорошо, я понял это. я думаю. я создал свой собственный класс хранилища пользователей и подключил его. это было несколько полезно. 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