配置问题与StructureMap.MVC5身份工作 [英] Issues Configuring StructureMap.MVC5 to work with Identity

查看:315
本文介绍了配置问题与StructureMap.MVC5身份工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前我正在试图从已永远不会正确摆在首位实现的旧版本(2.6)在升级后重新配置StructureMap在我们的应用程序。
我是新来使用DI容器,首先,和我为难以找到新的StructureMap版本查找文档。我卸载了旧的2.6版StructureMap和安装StructureMap.MVC5(因为我使用MVC5)。



我有是的AccountController的问题是什么。我已经StructureMap设置为使用参数的构造函数,但是当我的应用程序试图创建的UserManager,我得到一个出现InvalidOperationException 不owin.Environment项目是在上下文中找到。



很显然,我需要StructureMap额外的配置,但我不知道什么/如何。我能找到这个错误一百万来源,所有的暗示在web.config中添加标签,但他们都不是DI容器具体 - 当我使用StructureMap VS让框架创建控制器我只有这个问题。



下面是相关的代码; AccountController中的那款只是股票模板代码。



AccountController.cs



 私人ApplicationUserManager _userManager; 

公众的AccountController()
{
}

公众的AccountController(ApplicationUserManager的UserManager)
{
的UserManager =的UserManager;
}

公共ApplicationUserManager的UserManager
{
得到
{
//这就是抛出异常
返回_userManager ??
HttpContext.GetOwinContext()GetUserManager< ApplicationUserManager>();
}
私定
{
_userManager =价值;
}
}



DefaultRegistry.cs



 公共DefaultRegistry()
{
扫描(
扫描=>
{
扫描。 TheCallingAssembly();
scan.WithDefaultConventions();
scan.With(新ControllerConvention());
});

。对于< IBasicRepository>()
。使用< EntityRepository>()
.LifecycleIs< HttpContextLifecycle>()
.Ctor<串>(的ConnectionString)
。是(ConfigurationManager.ConnectionStrings [MyContext]的ConnectionString);

。对于<的AccountController>()
。使用<的AccountController>()
.SelectConstructor(()=>新建的AccountController());
}


解决方案

由于@Erik Funkenbusch指出,我是做竞争的事情。我最终作出的UserManager自动属性,去掉了参数的构造函数,并让StructureMap注入ApplicationUserManager。

 公共ApplicationUserManager的UserManager {得到;私人集; } 

公众的AccountController(ApplicationUserManager的UserManager)
{
的UserManager =的UserManager;
}



然后,我只是需要配置IUserStore和的DbContext的认同DefaultRegistry使用的.cs:

 对于< IUserStore< ApplicationUser,INT>>()
。使用< UserStore< ApplicationUser, CustomRole,INT,CustomUserLogin,
CustomUserRole,CustomUserClaim>>()
.LifecycleIs< HttpContextLifecycle>();

。对于<的DbContext>()
。用(()=>新建ApplicationDbContext())
.LifecycleIs< HttpContextLifecycle>();





这是所有我需要做的就是StructureMap.MVC工作与身份。



我最初挂断的部分是,我没有意识到的方式StructureMap.MVC(和其他DI容器)的工作。 (请参见我有关问题)。我希望它只是我的股票的AccountController它得到了由框架进行初始化(并认为这神奇的拦截对象的创建注入什么,我已经配置了工作),却没有意识到StructureMap必须初始化控制器本身为了使其构造进行注射。所以,当我遇到问题,我是A.奇怪,StructureMap有什么做与我摆在首位的AccountController(因为我没有明确的配置注射任何参数的 - 只为我的存储库中的其他控制器使用)和B我并没有考虑过改变我的股票代码,而是想着如何配置StructureMap。原来,我需要做两个。幸运的是,这是一个容易修改和我学到了一点更多关于DI容器是如何工作的。


I am currently trying to reconfigure StructureMap in our application after upgrading from an old version (2.6) that was never correctly implemented in the first place. I am new to using DI Containers to begin with, and am finding documentation for newer StructureMap versions hard to find. I uninstalled the old 2.6 version of StructureMap and installed StructureMap.MVC5 (since I am using MVC5).

What I am having issues with is the AccountController. I have StructureMap set up to use the parameterless constructor, but when my application tries to create the UserManager, I get an InvalidOperationException, "No owin.Environment item was found in the context."

Obviously I need additional configuration for StructureMap, but I have no idea what/how. I can find a million sources for this error, all suggesting adding a tag in web.config, but none of them seem to be DI container specific - and I only have this issue when I use StructureMap vs letting the framework create the controller.

Below is the relevant code; that section of the AccountController is just stock template code.

AccountController.cs

    private ApplicationUserManager _userManager;

    public AccountController()
    {
    }

    public AccountController(ApplicationUserManager userManager)
    {
        UserManager = userManager;
    }

    public ApplicationUserManager UserManager
    {
        get
        {
            // This is where the exception is thrown
            return _userManager ?? 
                HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
        }
        private set
        {
            _userManager = value;
        }
    }

DefaultRegistry.cs

    public DefaultRegistry() 
    {
        Scan(
            scan => 
            {
                scan.TheCallingAssembly();
                scan.WithDefaultConventions();
                scan.With(new ControllerConvention());
            });

        For<IBasicRepository>()
            .Use<EntityRepository>()
            .LifecycleIs<HttpContextLifecycle>()
            .Ctor<string>("ConnectionString")
            .Is(ConfigurationManager.ConnectionStrings["MyContext"].ConnectionString);

        For<AccountController>()
            .Use<AccountController>()
            .SelectConstructor(() => new AccountController());
    }

解决方案

As @Erik Funkenbusch pointed out, I was doing competing things. I ended up making UserManager an auto-property, removed the parameterless constructor, and let StructureMap inject the ApplicationUserManager.

    public ApplicationUserManager UserManager { get; private set; }

    public AccountController(ApplicationUserManager userManager)
    {
        UserManager = userManager;
    }

Then, I simply needed to configure the IUserStore and DbContext that Identity uses in DefaultRegistry.cs:

        For<IUserStore<ApplicationUser, int>>()
            .Use<UserStore<ApplicationUser, CustomRole, int, CustomUserLogin, 
                            CustomUserRole, CustomUserClaim>>()
            .LifecycleIs<HttpContextLifecycle>();

        For<DbContext>()
            .Use(() => new ApplicationDbContext())
            .LifecycleIs<HttpContextLifecycle>();  


This was all I needed to do to get StructureMap.MVC working with Identity.

Part of my initial hangup was that I didn't realize the way StructureMap.MVC (and other DI containers) worked. (See my related question.) I was expecting it to just work with my stock AccountController which got initialized by the framework (and thought it magically intercepted object creation to inject anything I had configured), not realizing that StructureMap must initialize the controllers itself in order for it to perform constructor injection. So when I ran into issues, I was A. Surprised that StructureMap had anything to do with my AccountController in the first place (since I wasn't explicitly configuring injection for any of its parameters - only for my Repository used in other controllers), and B. I wasn't thinking about changing my stock code but rather thinking about how to configure StructureMap. It turned out I needed to do both. Luckily, it was an easy modification and I learned a little more about how DI containers work.

这篇关于配置问题与StructureMap.MVC5身份工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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