首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >依赖关系没有正确注入mvc 5,owin,unity

依赖关系没有正确注入mvc 5,owin,unity
EN

Stack Overflow用户
提问于 2016-03-10 09:36:33
回答 1查看 2.7K关注 0票数 4

我正在使用ASP.NET MVC 5、EF6、ASP.NET Identity和users,我希望在构建网站时使用身份框架提供的功能来对用户进行操作和注册。

Startup.cs

代码语言:javascript
复制
public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            ConfigureAuth(app);
        }

    public void ConfigureAuth(IAppBuilder app)
    {
        // Configure the db context, user manager and signin manager to use a single instance per request
        app.CreatePerOwinContext(DbContext.Create);
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
        app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
        app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);



        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Auth/Login"),
            Provider = new CookieAuthenticationProvider
             {
                 // Enables the application to validate the security stamp when the user logs in.
                 // This is a security feature which is used when you change a password or add an external login to your account.  
                 OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
                    validateInterval: TimeSpan.FromMinutes(30),
                    regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
             }
        });
    }



}

IdentityConfig.cs

代码语言:javascript
复制
public class EmailService : IIdentityMessageService
    {
        public async Task SendAsync(IdentityMessage message)
        {
            await configSendGridasync(message);
        }

    private async Task configSendGridasync(IdentityMessage message)
    {
        var myMessage = new SendGridMessage();
        myMessage.AddTo(message.Destination);
        myMessage.From = new System.Net.Mail.MailAddress("John@Smith.ko", "JOhn Smith");
        myMessage.Subject = message.Subject;
        myMessage.Text = message.Body;
        myMessage.Html = message.Body;

        var creds = new NetworkCredential("user", "pass");

        var transport = new Web(creds);

        if (transport != null)
        {
            await transport.DeliverAsync(myMessage);
        }
        else
        {
            Trace.TraceError("Failed to create Web transport.");
            await Task.FromResult(0);
        }
    }
}


// Configure the application user manager used in this application. UserManager is defined in ASP.NET Identity and is used by the application.
public class ApplicationUserManager : UserManager<ApplicationUser>
{
    public ApplicationUserManager(IUserStore<ApplicationUser> store)
        : base(store)
    {
    }

    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
    {
        var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<DbContext>()));
        // Configure validation logic for usernames
        manager.UserValidator = new UserValidator<ApplicationUser>(manager)
        {
            AllowOnlyAlphanumericUserNames = false,
            RequireUniqueEmail = true
        };

        // Configure validation logic for passwords
        manager.PasswordValidator = new PasswordValidator
        {
            RequiredLength = 6,
            RequireNonLetterOrDigit = false,
            RequireDigit = true,
            RequireLowercase = true,
            RequireUppercase = false,
        };

        // Configure user lockout defaults
        manager.UserLockoutEnabledByDefault = true;
        manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
        manager.MaxFailedAccessAttemptsBeforeLockout = 5;
        manager.EmailService = new EmailService();

        var dataProtectionProvider = options.DataProtectionProvider;
        if (dataProtectionProvider != null)
        {
            manager.UserTokenProvider =
                new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));

        }
        return manager;
    }
}

// Configure the application sign-in manager which is used in this application.
public class ApplicationSignInManager : SignInManager<ApplicationUser, string>
{
    public ApplicationSignInManager(ApplicationUserManager userManager, IAuthenticationManager authenticationManager)
        : base(userManager, authenticationManager)
    {
    }

    public override Task<ClaimsIdentity> CreateUserIdentityAsync(ApplicationUser user)
    {
        return user.GenerateUserIdentityAsync((ApplicationUserManager)UserManager);
    }

    public static ApplicationSignInManager Create(IdentityFactoryOptions<ApplicationSignInManager> options, IOwinContext context)
    {
        return new ApplicationSignInManager(context.GetUserManager<ApplicationUserManager>(), context.Authentication);
    }
}

public class ApplicationRoleManager : RoleManager<IdentityRole>
{
    public ApplicationRoleManager(IRoleStore<IdentityRole, string> roleStore)
        : base(roleStore)
    {
    }
    public static ApplicationRoleManager Create(
        IdentityFactoryOptions<ApplicationRoleManager> options,
        IOwinContext context)
    {
        var manager = new ApplicationRoleManager(
            new RoleStore<IdentityRole>(
                context.Get<DbContext>()));

        return manager;
    }
}

UnityConfig.cs

代码语言:javascript
复制
public class UnityConfig
    {
        #region Unity Container
        private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
        {
            var container = new UnityContainer();
            RegisterTypes(container);
            return container;
        });

    /// <summary>
    /// Gets the configured Unity container.
    /// </summary>
    public static IUnityContainer GetConfiguredContainer()
    {
        return container.Value;
    }
    #endregion

    public static void RegisterTypes(IUnityContainer container)
    {
        #region AutoMapper DI
        var config = new MapperConfiguration(cfg =>
        {
            cfg.AddProfile<AutoMapperWebProfileConfiguration>();
        });

        var mapper = config.CreateMapper();
        container.RegisterInstance(config.CreateMapper());

        #endregion

        #region userManager and roleManager DI 
        var accountInjectionConstructor = new InjectionConstructor(new DbContext());
        container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(accountInjectionConstructor);
        container.RegisterType<IRoleStore<IdentityRole, string>,
            RoleStore<IdentityRole, string, IdentityUserRole>>(accountInjectionConstructor);

        #endregion

        #region AuthenticationManager
        container.RegisterType<IAuthenticationManager>(new InjectionFactory(o => HttpContext.Current.GetOwinContext().Authentication));

        #endregion
        #region IdentityConfig injects
        container.RegisterType<DbContext>();
        container.RegisterType<ApplicationSignInManager>();
        container.RegisterType<ApplicationUserManager>();
        container.RegisterType<EmailService>();
        container.RegisterType<IMappingEngine>(new InjectionFactory(_ => Mapper.Engine));
        #endregion


   }
}

AuthController.cs

代码语言:javascript
复制
public class AuthController : Controller
{

    private IMapper mapper;
    private RoleManager<IdentityRole> roleManager;
    private IAuthenticationManager authManager;
    private ApplicationUserManager userManager;
    private ApplicationSignInManager signInManager;

    public AuthController(IMapper mapper, IRoleStore<IdentityRole, string> roleStore, IAuthenticationManager authManager, ApplicationUserManager userManager, ApplicationSignInManager signInManager)
    {
        this.mapper = mapper;
        this.roleManager = new RoleManager<IdentityRole>(roleStore);
        this.authManager = authManager;
        this.userManager = userManager;
        this.signInManager = signInManager;

    } //rest omitted for brevity.

问题

当我运行代码时,Startup.cs中的所有内容都会被执行,所有对象都会从IdentityConfig.cs中实例化,因此我得到了一个具有所有所需属性集(email服务、userTokenprovider等)的UserManager实例,但是当到达控制器时,会注入另一个没有设置这些属性的对象,因此我得到了许多异常(例如,未注册的IUserTokenProvider等等)。我假设注入到Controller中的UserManager是由Unity注入的,而不是由Startup.cs创建的。与控制器中定义的rest私有属性的故事相同。我如何告诉Unity使用Startup.cs创建的对象?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-03-11 08:27:18

很明显,OWIN和Unity正在您的代码中创建自己的标识对象,因此取决于使用,您将收到不同的对象。为了避免这一点,你必须决定哪一个人负责创建你的对象,拥有还是统一。由于建议让DI做这样的事情,所以最好像这样更改启动文件:

代码语言:javascript
复制
public void ConfigureAuth(IAppBuilder app)
{
    app.CreatePerOwinContext(()=> DependencyResolver.Current.GetService<ApplicationUserManager>());
    app.CreatePerOwinContext(()=> DependencyResolver.Current.GetService<ApplicationSignInManager>());
    // other configs
}

现在OWIN从Unity获得了相同的对象。但是,您还需要一些额外的配置和考虑,以整合统一和身份。I've already answered this看过了。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35912600

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档