gpt4 book ai didi

c# - 依赖项未正确注入(inject) mvc 5、owin、unity

转载 作者:行者123 更新时间:2023-11-30 20:37:33 31 4
gpt4 key购买 nike

我正在使用 ASP.NET MVC 5、EF6、ASP.NET Identity 和 Unity 作为 IoC,我想在构建网站时使用 Identity 框架提供的功能来处理用户和注册。

Startup.cs

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

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

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

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 中实例化,因此我得到了一个 UserManager 实例,它具有所有需要的属性集(电子邮件服务、userTokenprovider 等),但是当到达我的 Controller ,注入(inject)另一个没有设置这些属性的对象,因此我得到很多异常(例如 IUserTokenProvider 未注册等)。我假设注入(inject)到 Controller 中的 UserManager 是 Unity 注入(inject)的,而不是 Startup.cs 创建的。与 Controller 中定义的其余私有(private)属性相同。我如何告诉 Unity 使用由 Startup.cs 创建的对象?

最佳答案

显然,OWIN 和 Unity 在您的代码中创建自己的 Identity 对象,因此根据使用情况,您会收到不同的对象。为避免这种情况,您必须决定由 OWIN 还是 Unity 负责创建您的对象。由于建议让 DI 做这样的事情,因此最好像这样更改您的启动文件:

public void ConfigureAuth(IAppBuilder app)
{
app.CreatePerOwinContext(()=> DependencyResolver.Current.GetService<ApplicationUserManager>());
app.CreatePerOwinContext(()=> DependencyResolver.Current.GetService<ApplicationSignInManager>());
// other configs
}

现在 OWIN 从 Unity 获取相同的对象。但是您还需要一些额外的配置和考虑才能将 Unity 与 Identity 集成。 I've already answered this看看。

关于c# - 依赖项未正确注入(inject) mvc 5、owin、unity,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35912600/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com