Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/34.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用Ninject OWIN中间件在OWIN启动中注入依赖项UserStore_C#_Asp.net_Dependency Injection_Ninject_Owin - Fatal编程技术网

C# 使用Ninject OWIN中间件在OWIN启动中注入依赖项UserStore

C# 使用Ninject OWIN中间件在OWIN启动中注入依赖项UserStore,c#,asp.net,dependency-injection,ninject,owin,C#,Asp.net,Dependency Injection,Ninject,Owin,在使用OWIN请求管道创建ApplicationUserManager时,使用依赖项注入创建自定义UserStore时遇到问题 背景 我正在尝试将web应用程序中的用户功能从使用SimpleMembership迁移到新的ASP.NET标识。启动新的MVC5项目时,单页应用程序的默认实现使用ASP.Identity,使用实体框架实现UserStore功能 在我的例子中,我们已经使用NHibernate作为ORM,并使用ninject实现工作单元模式,这样每个请求都有一个NHibernate会话,我

在使用OWIN请求管道创建ApplicationUserManager时,使用依赖项注入创建自定义UserStore时遇到问题

背景

我正在尝试将web应用程序中的用户功能从使用SimpleMembership迁移到新的ASP.NET标识。启动新的MVC5项目时,单页应用程序的默认实现使用ASP.Identity,使用实体框架实现UserStore功能

在我的例子中,我们已经使用NHibernate作为ORM,并使用ninject实现工作单元模式,这样每个请求都有一个NHibernate会话,我想让ASP.Identity与我们现有的框架一起工作

为此,我创建了一个自定义UserStore,它可以通过注入相关的存储库/nhibernate会话等来创建。然后可以使用Ninject将其注入控制器的构造函数中,而不是使用默认实现的GetOwinContext功能

为了做到这一点,我在启动的ConfigureAuth(IAppBuilder app)方法中注释掉了以下行,该方法默认创建UserManager类:

// app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
但是,Ninject.Web.Common.OwinHost没有公开其内核,因此我无法使用服务位置模式将值注入Create回调中的自定义UserStore

我还尝试创建一个单例内核,并使用app.CreatePerOwinContext(CreateKernel)向相关委托注册该内核,以便以后可以访问该内核,但当我调用context.Get()时,它只返回null

问题

如何使用CreatePerOwinContext注册回调函数来创建使用自定义UserStore的自定义UserManager,然后使用Ninject在创建回调中使用依赖项注入来创建自定义UserStore,以便我还可以访问Owin用于注入用户令牌提供程序的IdentityFactoryOptions

有关信息:

可以将内核注册为单例,以便ninject中间件可以使用相同的内核,并且也可以在owin上下文中注册

    public static StandardKernel CreateKernel()
    {
        if (_kernel == null)
        {
            _kernel = new StandardKernel();
            _kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

            _kernel.Load(Assembly.GetExecutingAssembly(), Assembly.Load("Super.CompositionRoot"));
        }
        return _kernel;
    }
公共静态标准内核CreateKernel()
{
if(_kernel==null)
{
_内核=新的标准内核();
_kernel.Bind().To();
_Load(Assembly.getExecutionGassembly(),Assembly.Load(“Super.CompositionRoot”);
}
返回内核;
}
回调函数app.CreatePerOwinContext(ApplicationUserManager.Create)将调用ApplicationUserManager.Create,而不是注册它以便在安装过程中稍后调用。因此,需要在ApplicationUserManager的创建回调之前注册CreateKernel函数,否则,如果您试图从该方法内的owin上下文中获取内核,则会出现空引用异常

    public void ConfigureAuth(IAppBuilder app)
    {
        app.CreatePerOwinContext(CreateKernel);
        app.UseNinjectMiddleware(CreateKernel);
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
     }
public void ConfigureAuth(IAppBuilder应用程序)
{
app.CreatePerOwinContext(CreateKernel);
app.usenject中间件(CreateKernel);

app.CreatePerOwinContext,但不知道在请求完成时提交任何未完成事务的最合适方式。

注意这是针对WebApi的(使用
System.Web.Http

好吧,我使用了
System.Web
中的东西,这是一种欺骗,我们本应该将自己从这个名称空间中剔除,但尽管它仍然被使用,为什么不呢

首先,我使用了这个问题的一些助手:

其中,解析器已在
System.Web
的全局配置中注册。因此,我只需在需要时抓取它:

    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
    {
        var repository = System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver
                            .GetService(typeof(Data.Repositories.UserRepository)) as Data.Repositories.UserRepository;

        var manager = new ApplicationUserManager(repository);
...

我已经查看、查看并反映了libs,但找不到该方法!如果我知道该方法是如何工作的,我们可能会找到另一种方法来创建令牌,即不需要选项实例。

我不知道Ninject中是否自发布以来发生了更改,但当您在
UseNin注册
CreateKernel
时jectMiddleware
我得到错误:
System.InvalidOperationException:序列不包含任何元素
来自
NinJectMVHttpApplicationPlugin
@ShayNissel你知道为什么会得到一个序列不包含元素的错误吗?我遇到了同样的问题。@Riddle Methis你看到序列不包含元素了吗错误?@thebringking我无法用
UseinjectMiddleware
解决这个问题,我假设(由于缺乏适当的文档),它从未针对MVC5进行过完全修改和测试,只是针对WebAPI。为什么
app.CreatePerOwinContext(CreateKernel);
app.UseinjectMiddleware(CreateKernel)
?当我这样做时,它会弄乱绑定。我可以第一次从ninject获取绑定,但第二次尝试总是失败。删除
CreatePerOwinContext
似乎可以解决它。
    public static StandardKernel CreateKernel()
    {
        if (_kernel == null)
        {
            _kernel = new StandardKernel();
            _kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

            _kernel.Load(Assembly.GetExecutingAssembly(), Assembly.Load("Super.CompositionRoot"));
        }
        return _kernel;
    }
    public void ConfigureAuth(IAppBuilder app)
    {
        app.CreatePerOwinContext(CreateKernel);
        app.UseNinjectMiddleware(CreateKernel);
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
     }
    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
    {
        var kernel = context.Get<StandardKernel>();
        var userStore = kernel.Get<IUserStore<User, int>>();
        var manager = new ApplicationUserManager(userStore);
        //...
    }
    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
    {
        var repository = System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver
                            .GetService(typeof(Data.Repositories.UserRepository)) as Data.Repositories.UserRepository;

        var manager = new ApplicationUserManager(repository);
...
    public void ConfigureAuth(IAppBuilder app)
    {
        // Dependency Injection

        Evoq.AppName.Configuration.Ninject.NinjectHttpContainer.RegisterAssembly();

        // Configure the db context and user manager to use a single instance per request

        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);

...
    /// <summary>
    /// Registers a callback that will be invoked to create an instance of type T that will be stored in the OwinContext which can fetched via context.Get
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="app"></param>
    /// <param name="createCallback"></param>
    /// <returns></returns>
    public static IAppBuilder CreatePerOwinContext<T>(this IAppBuilder app, Func<IdentityFactoryOptions<T>, IOwinContext, T> createCallback) where T : class,IDisposable {
        if (app == null) {
            throw new ArgumentNullException("app");
        }
        if (createCallback == null) {
            throw new ArgumentNullException("createCallback");
        }

        app.Use(typeof(IdentityFactoryMiddleware<T, IdentityFactoryOptions<T>>),
            new IdentityFactoryOptions<T>() {
                DataProtectionProvider = app.GetDataProtectionProvider(),
                Provider = new IdentityFactoryProvider<T>() {
                    OnCreate = createCallback
                }
            });
        return app;
    }