I am following Onion Architecture and using Identity Framework. In my Core project, I have:
public interface IUserRepository : IDisposable
{
// Repository methods.......
}
In my Architecture.Repository, I have
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;
}
}
In my dependency resolution project, I have:
[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)
};
}
}
}
On container.Verify()
, I am getting the following error:
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.
Can someone guide me what I am doing wrong and what I need to do to correct it?
The exception message says:
The exception suggests that you should make a registration for
IUserStore<AppUser, int>
, because theUserManager<AppUser, int>
depends on this. So you could for instance make the following registration:However, according to this article, you should not auto-wire framework types such as
UserManager<TUser, TKey>
, but use manual registration instead by creating such type yourself. For instance:It would be even better to refrain from using types from external libraries (such as the
UserManager<TUser, TKey>
) directly in your core application. Especially since you are practicing the Onion architecture. This architecture promotes SOLID principles and describes the concept of ports and adapters. A port is an abstraction defined by your application that allows a gateway into some external domain or library. An adapter is an implementation of such abstraction that actually connects to this external domain or library. This is exactly what the Dependency Inversion Principle (one of the five SOLID principles) describes.So instead of letting your
UserRepository
depend on a framework type such asUserManager<TUser, TKey>
, let it depend on a customly defined abstraction, with a very narrowly defined and single responsibility. The adapter for this abstraction can on its turn useUserManager<TUser, TKey>
.Depending on what
UserRepository
does, you might even consider thisUserRepository
itself an adapter. In this case, lettingUserRepository
depend directly onUserManager<TUser, TKey>
is fine. In that case, hiding theUserManager<TUser, TKey>
behind an extra abstraction just causes an extra/needless layer of abstraction.But nonetheless, the adapter can not only directly depend on
UserManager<TUser, TKey>
, but it can simply control the creation and destruction ofUserManager<TUser, TKey>
itself. In other words, yourUserRepository
can look as follows:In the Simple Injector discussions there is an interesting description about how to work with Identity and Visual Studio's default template. And here is a Stackoverflow q/a about Identity that you might find interesting as well.