简单的喷油器的UserManager身份与LT; APPUSER,的Int32>注册错误 [英] Simple Injector Identity UserManager<AppUser, Int32> Registration Error

查看:260
本文介绍了简单的喷油器的UserManager身份与LT; APPUSER,的Int32>注册错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我下面洋葱架构和使用Identity框架。在我的核心项目,我有:

I am following Onion Architecture and using Identity Framework. In my Core project, I have:

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

在我Architecture.Repository,我有

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)
            };
        }
    }
}

container.Verify(),我收到以下错误:

'System.InvalidOperationException'类型的异常出现在SimpleInjector.dll但在用户code没有处理

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

其他信息:配置无效。创建
  实例类型IUserRepository失败。注册委托
  键入IUserRepository引发了异常。没有登记的类型
  的UserManager可以发现和隐
  登记不能进行。类的构造函数
  的UserManager包含类型的参数
  IUserStore与未注册名称'商店'。
  请确保IUserStore注册,或改变
  的UserManager的构造。

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?

推荐答案

异常消息称:

型的UserManager 1所述的构造; APPUSER,int>的包含类型的参数
  IUserStore与未注册名称'商店'。请确保
  IUserStore&LT; APPUSER,int>的注册或更改的UserManager的构造

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&LT; APPUSER,INT&GT; ,因为的UserManager&LT; APPUSER,INT&GT; 取决于此。所以,你可以为实例进行以下注册:

The exception suggests that you should make a registration for IUserStore<AppUser, int>, because the UserManager<AppUser, int> depends on this. So you could for instance make the following registration:

// 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);

不过,根据这篇文章,你不应该自动线框架类型,如的UserManager&LT; TUSER,TKEY的&GT; ,而是通过建立这种类型的自己使用手动注册。例如:

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:

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

这将是更好的使用来自外部库类型(如的UserManager&LT; TUSER,TKEY的&GT; ),以避免直接在您的核心应用。特别是因为你正在练习洋葱架构。这个体系结构促进固体的原理和描述的端口和适配器的概念。端口是由您的应用程序,允许一个网关到一些外部域或库中定义的抽象。适配器是这样抽象的实现,实际上连接到该外部域或库。这也正是依赖倒置原则(五SOLID原则之一)描述。

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.

因此​​,而不是让你的 UserRepository 取决于框架类型,如的UserManager&LT; TUSER,TKEY的&GT; ,让它依赖于一个customly定义的抽象,用定义非常狭窄并的单一职责。这个抽象的适配器就可以反过来利用的UserManager&LT; TUSER,TKEY的方式&gt;

So instead of letting your UserRepository depend on a framework type such as UserManager<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 use UserManager<TUser, TKey>.

根据什么 UserRepository 呢,你甚至可以考虑这个 UserRepository 本身的适配器。在这种情况下,让 UserRepository 是否取决于直接在的UserManager&LT; TUSER,TKEY的&GT; 的罚款。在这种情况下,隐藏的UserManager&LT; TUSER,TKEY的&GT; 背后的一个额外的抽象正义事业额外的抽象/不必要的层

Depending on what UserRepository does, you might even consider this UserRepository itself an adapter. In this case, letting UserRepository depend directly on UserManager<TUser, TKey> is fine. In that case, hiding the UserManager<TUser, TKey> behind an extra abstraction just causes an extra/needless layer of abstraction.

但无论如何,适配器不仅可以直接依赖于的UserManager&LT; TUSER,TKEY的&GT; ,但它可以简单地控制的创建和销毁的UserManager&LT; TUSER,TKEY的&GT; 本身。换句话说,你的 UserRepository 可以看看如下:

But nonetheless, the adapter can not only directly depend on UserManager<TUser, TKey>, but it can simply control the creation and destruction of UserManager<TUser, TKey> itself. In other words, your UserRepository can look as follows:

// 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;
         }
     }
}

在简单的喷油器的讨论有一个有趣的描述有关如何处理工作身份和Visual Studio的默认模板。和<一个href=\"https://stackoverflow.com/questions/27447757/register-iauthenticationmanager-with-simple-injector/28948205#28948205\">here是关于身份,你可能会觉得有趣也出现StackOverflow Q / A。

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.

这篇关于简单的喷油器的UserManager身份与LT; APPUSER,的Int32&GT;注册错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆