ASP.net Session_Start方法中的dependency injection
我正在学习dependency injection并首次使用autofac。 我在几个autofac示例(见下文)中提到了构建容器,并从我的application_start调用
public class ContainerConfig { public static void RegisterContainer() { //Create a new ContainerBuilder var builder = new ContainerBuilder(); // Register all the controllers using the assembly object builder.RegisterControllers(Assembly.GetExecutingAssembly()); //Registering default convention -- IExample and Example builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()) .Where(t => t.Name.Single(i => i.Name == "I" + t.Name)) .AsImplementedInterfaces(); //Build the container var container = builder.Build(); //Set the default resolver to use Autofac DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); } }
我使用IUserService在我的Core项目中创建了UserService。 这有使dbcall从表中获取用户信息的方法。 在我的UI项目中,我有一个名为UserProvider的类,我想要注入UserService。
public class UserProvider { private readonly IUserService _userService; public UserProvider(IUserService userService) { _userService = userService; } public void LoadCurrentUser() { Users FoundUser = _userService.ImportOrGetUser(); if (FoundUser != null) { //add it to session CurrentUser = FoundUser; } } }
这个UserProvider,我在session_start中使用
void Session_OnStart() { UserProvider OUsrPrv = new UserProvider(new UserService()); OUsrPrv.LoadCurrentUser(); }
在上面的代码中,如果我传递’new UserService()’,我的理解是我手动注入UserService。 我不知道autofac如何在这里提供帮助。 谷歌中的所有示例都在谈论MVCController或WebApiController中的dependency injection,而不是像我正在做的那样在个别类(UserProvider)中。
请有人请点亮一下吗? 我做错了吗?
System.Web.HttpApplication
的事件模型是ASP.NET的一部分,而不是MVC。 它不是为与dependency injection一起使用而设计的。
Cyril建议的答案是使用服务定位器来获取对服务的引用。 这远非理想,因为您在代码中对服务定位器进行依赖。
以MVC为中心的实现横切关注点(例如将用户数据加载到会话状态)的方法是使用全局注册的filter。 您可以实现IAuthorizationFilter
或IActionFilter
以获得所需的效果。 在这种情况下,使用IActionFilter
是有意义的,因为您要等到确定在被调用之前有授权用户。
注意:虽然这可以回答您的具体问题,但最好不要在MVC中使用会话状态。 另一种方法是使用ASP.NET Identity with Claims来存储用户配置文件数据,而不是使用Session。
using System; using System.Web.Mvc; using System.Security.Principal; public class GetUserActionFilter : IActionFilter { private readonly IUserRepository userRepository; public GetUserActionFilter(IUserRepository userRepository) { if (userRepository == null) throw new ArgumentNullException("userRepository"); this.userRepository = userRepository; } public void OnActionExecuted(ActionExecutedContext filterContext) { // Do nothing - this occurs after the action method has run } public void OnActionExecuting(ActionExecutingContext filterContext) { IPrincipal user = filterContext.HttpContext.User; if (user == null) { return; } IIdentity identity = user.Identity; if (identity == null) { return; } // Make sure we have a valid identity and it is logged in. if (identity.IsAuthenticated) { string key = "__CurrentUserData"; var userData = filterContext.HttpContext.Session[key]; if (userData == null) { // User data doesn't exist in session, so load it userData = userRepository.GetUserData(identity.Name); // Add it to session state filterContext.HttpContext.Session[key] = userData; } } } }
现在,要全局添加filter,您需要:
- 使用Autofac注册filter及其依赖项。
- 将容器传递给静态
RegisterGlobalFilters
方法。
注册filter
使用命名实例将其与其他潜在的IActionFilter
实例区分开来。
builder.RegisterType() .Named("getUserActionFilter");
通过容器
FilterConfig.cs
public class FilterConfig { public static void RegisterGlobalFilters(GlobalFilterCollection filters, IContainer container) { filters.Add(container.ResolveNamed("getUserActionFilter")); filters.Add(new HandleErrorAttribute()); } }
的Global.asax.cs
public class MvcApplication : System.Web.HttpApplication { // This method serves as the composition root // for the project. protected void Application_Start() { // Register Autofac DI IContainer container = ContainerConfig.RegisterContainer(); AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters, container); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); AuthConfig.RegisterAuth(); } }
ContainerConfig.cs
public class ContainerConfig { public static IContainer RegisterContainer() { //Create a new ContainerBuilder var builder = new ContainerBuilder(); // Register all the controllers using the assembly object builder.RegisterControllers(Assembly.GetExecutingAssembly()); //Registering default convention -- IExample and Example builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()) .Where(t => t.Name.Single(i => i.Name == "I" + t.Name)) .AsImplementedInterfaces(); // Register our filter builder.RegisterType() .Named("getUserActionFilter"); //Build the container var container = builder.Build(); //Set the default resolver to use Autofac DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); // Return the container to our composition root. return container; } }
请注意,我刚刚在这里使用了存储库服务,因为HttpContext
已经通过动作filter直接可用,并且这里需要额外的逻辑,因为我们不确定它是否存在于会话状态中,或者是否存在用户查找,所以我们的filter除了加载会话状态外还会执行这些检查。
为了正确使用dependency injection ,您永远不应该自己创建实例,底层框架应该为您提供实例。
但ASP.net在没有任何dependency injection的情况下调用Session_OnStart
。 在这种情况下,您可以使用DependencyResolver.Current
静态属性来解析所请求的服务。
上述就是C#学习教程:ASP.net Session_Start方法中的dependency injection分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
void Session_OnStart() { UserProvider userProvider = DependencyResolver.Current.GetService(); userProvider.LoadCurrentUser(); }
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1038678.html