1

Я следую за архитектурой Луны и использую Identity Framework. В моей Основной проект, у меня есть:Simple Injector Identity UserManager <AppUser, Int32> Ошибка регистрации

public interface IUserRepository : IDisposable 
{ 
    // Repository methods....... 
} 

В моем Architecture.Repository, я

public class UserRepository : IUserRepository 
{ 
    // This is Identity UserManager 
    private readonly UserManager<AppUser, int> _userManager; 
    private readonly IAuthenticationManager _authenticationManager; 
    private bool _disposed; 

    public UserRepository(UserManager<User, int> userManager, 
     IAuthenticationManager authenticationManager) 
    { 
      _userManager = userManager; 
      _authenticationManager = authenticationManager; 
    } 
} 

В моей разрешения проекта зависимостей, у меня есть:

[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(IocConfig), 
    "RegisterDependencies")] 
namespace AdShad.Infrastructure.DependencyResolution 
{ 
    public class IocConfig 
    { 
     public static void RegisterDependencies() 
     { 
      var container = new Container(); 
      container.RegisterWebApiRequest<IUnitOfWork, UnitOfWork>(); 
      container.RegisterWebApiRequest<IUserRepository, UserRepository>(); 

      container.RegisterManyForOpenGeneric(typeof(IRepository<>), 
       typeof(BaseRepository<>).Assembly); 
      container.RegisterWebApiRequest<IEntitiesContext, MyContext>(); 

      container.RegisterWebApiRequest(
       () => HttpContext.Current.GetOwinContext().Authentication); 

      container.Verify(); 

      HttpConfiguration config = new HttpConfiguration 
      { 
       DependencyResolver = 
        new SimpleInjectorWebApiDependencyResolver(container) 
      }; 
     } 
    } 
} 

На container.Verify() я я получаю следующую ошибку:

An exception of type 'System.InvalidOperationException' occurred in SimpleInjector.dll but was not handled in user code

Additional information: The configuration is invalid. Creating the instance for type IUserRepository failed. The registered delegate for type IUserRepository threw an exception. No registration for type UserManager could be found and an implicit registration could not be made. The constructor of type UserManager contains the parameter of type IUserStore with name 'store' that is not registered. Please ensure IUserStore is registered, or change the constructor of UserManager.

Может ли кто-нибудь вести меня, что я делаю неправильно, и что мне нужно сделать, чтобы исправить это?

+0

Но у вас нет учетной записи 'UserManager' в контейнере ... и исключение говорит об этом, что' UserManager' constuctor требует параметра 'IUserStore', поэтому SimpleInjector не может его создать. Вам нужно зарегистрировать 'IUserStore' в контейнере или делегировать для класса UserManager –

+0

Но у меня нет IUserStore и нет конкретного класса для этого интерфейса, как я могу зарегистрироваться? –

+0

@UsmanKhalid вам нужно будет выбрать реализацию UserStore или создать свой собственный ([здесь] (http://www.asp.net/identity/overview/getting-started/adding-aspnet-identity-to-an -пути-или-существующий-веб-формы-проект), [здесь] (http://www.asp.net/identity/overview/extensibility/overview-of-custom-storage-providers-for-aspnet-identity) и т.п.) – qujck

ответ

5

Сообщение об исключении говорит:

The constructor of type UserManager<AppUser, int> contains the parameter of type IUserStore with name 'store' that is not registered. Please ensure IUserStore<AppUser, int> is registered, or change the constructor of UserManager.

Исключение предполагает, что вы должны сделать регистрацию IUserStore<AppUser, int>, потому что UserManager<AppUser, int> зависит от этого. Таким образом, можно, например, сделать следующую регистрацию:

// UserStore<TUser> is defined in Microsoft.AspNet.Identity.EntityFramework. 
// Do note that UserStore<TUser> implements IUserStore<TUser, string>, so 
// this Entity Framework provider requires a string. If you need int, you 
// might have your own store and need to build your own IUserStore implemenation. 
container.Register<IUserStore<AppUser, string>>(
    () => new UserStore<AppUser>>(), 
    Lifestyle.Scoped); 

Однако, по словам this article, вы не должны автоматически проволочные типа рамки, такие как UserManager<TUser, TKey>, но использовать ручной регистрации, а не путем создания такого типа самостоятельно. Например:

container.Register<UserManager<AppUser, string>>(
    () => new UserManager<AppUser, string>(new UserStore<AppUser>()), 
    Lifestyle.Scoped); 

Было бы еще лучше воздержаться от использования типов из внешних библиотек (например, UserManager<TUser, TKey>) непосредственно в основной заявке. Тем более, что вы практикуете лунную архитектуру. Эта архитектура способствует принципам SOLID и описывает концепцию портов и адаптеров. Порт представляет собой абстракцию, определенную вашим приложением, которая позволяет шлюз в какой-либо внешний домен или библиотеку. Адаптер представляет собой реализацию такой абстракции, которая фактически соединяется с этим внешним доменом или библиотекой. Это именно то, что описывает Dependency Inversion Principle (один из пяти принципов SOLID).

Таким образом, вместо того, чтобы позволить вашей UserRepository зависеть от каркасного типа, такие как UserManager<TUser, TKey>, пусть это зависит от customly определенной абстракции, с very narrowly defined и single responsibility. Адаптер для этой абстракции может в свою очередь использовать UserManager<TUser, TKey>.

В зависимости от того, что UserRepository делает, вы можете даже подумать об этом UserRepository сам адаптер. В этом случае разрешение UserRepository зависит напрямую от UserManager<TUser, TKey> в порядке. В этом случае скрытие UserManager<TUser, TKey> за дополнительной абстракцией просто вызывает лишний/ненужный уровень абстракции.

Но, тем не менее, адаптер может не только напрямую зависеть от UserManager<TUser, TKey>, но он может просто контролировать создание и уничтожение самого UserManager<TUser, TKey>. Другими словами, ваш UserRepository может выглядеть следующим образом:

// NOTE: Do not let IUserRepository implement IDisposable. This violates 
// the Dependency Inversion Principle. 
// NOTE2: It's very unlikely that UserRepository itself needs any disposal. 
public class UserRepository : IUserRepository 
{ 
    // This is Identity UserManager 
    private readonly IAuthenticationManager _authenticationManager; 

    public UserRepository(IAuthenticationManager authenticationManager) 
    { 
      _authenticationManager = authenticationManager; 
    } 

    public void Delete(AppUser user) { 
     // Here we create and dispose the UserManager during the execution 
     // of this method. 
     using (manager = new UserManager<AppUser, string>(
      new UserStore<AppUser>())) { 
      manager.DeleteAsync(user).Result; 
     } 
    } 
} 

В простых дискуссиях инжектора есть interesting description о том, как работать с идентификацией и шаблона Visual Studio по умолчанию.И here - это Stackoverflow q/a о Identity, который может оказаться интересным.

+0

спасибо. Это большая помощь. На самом деле я совершенно не знаком с архитектурой лука и простым инжектором. Есть некоторые ограничения со стороны клиента, которые я должен использовать Onion Architecture, используя первый подход db и структуру ASP.NET Identity. Я не нахожу достаточной помощи в Интернете по моему требованию. Но так или иначе большое спасибо. Я дойду до всех этих статей и попытаюсь их реализовать. –

+0

Я не знаю, что вы пытаетесь сказать здесь: «вам не следует автоматически создавать типы каркасов, такие как UserManager , но вместо этого вручную используйте регистрацию вручную, создав такой тип самостоятельно». Вы пытаетесь сказать, что я не должен настраивать Identity UserManager? –

+0

@UsmanKhalid: нет, автоматическая проводка - это процесс, в котором контейнер выбирает правый конструктор и автоматически вводит правильные зависимости. Ручная проводка - это то, где ваш код вызывает этот конструктор. Это то, что делают мои примеры. Они называют ctor внутри выражения лямбды. – Steven

Смежные вопросы