c# - 如何在 WebApi 中为属性实现 DI?

标签 c# dependency-injection attributes ninject asp.net-web-api

我重构了一个在 Web api 中实现 Basic Http Authentication 的属性,使其具有如下 DI:

 public class BasicHttpAuthAttribute : ActionFilterAttribute
    {
        private readonly ILoginManager _manager;

        public BasicHttpAuthAttribute(ILoginManager manager)
        {
            this._manager = manager;
        }
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            if (actionContext.Request.Headers.Authorization == null)
            {
                actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
                actionContext.Response.Content = new StringContent("Missing Auth-Token");
            }
            else
            {

                var authToken = actionContext.Request.Headers.Authorization.Parameter;
                var decodedToken = Encoding.UTF8.GetString(Convert.FromBase64String(authToken));

                string userName = decodedToken.Substring(0, decodedToken.IndexOf(":"));
                string password = decodedToken.Substring(decodedToken.IndexOf(":") + 1);


                UserInfo user;


                if (_manager.LoginPasswordMatch(userName, password, out user))
                {
                    var apiUser = new ApiUser(user.UserID);
                    HttpContext.Current.User = new GenericPrincipal(new ApiIdentity(apiUser), new string[]{});

                    base.OnActionExecuting(actionContext);

                }
                else
                {
                    actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
                    actionContext.Response.Content = new StringContent("Invalid username or password");
                }



            }
        }
    }

在重构之前,我在 OnActionExecuting 中创建了一个 LoginManager 实例(它本身没有 DI,所以我可以使用 ctor 创建一个实例)。重构后的问题是构建失败,因为当我将过滤器应用于 WebApi 方法时,它期望在那里有一个参数。

在这种情况下,我该如何实现 DI,因为 LoginManager 本身在其构造函数中采用 ILoginRepository?有可能吗?

最佳答案

这并不容易,因为在 Web API 中处理属性的方式与您可能期望的有点不同。首先它们是在不同的时间点创建的,其次它们被缓存。

话虽如此,实现 DI 最简单的方法是在处理时调用您选择的 DI 框架,然后检索依赖项,即在您的 onActionExecuting 中,而不是通过构造函数注入(inject)>:

var s = GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IService));

关于c# - 如何在 WebApi 中为属性实现 DI?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12602059/

相关文章:

c# - 在 WCF 中使用 Unity 将依赖项注入(inject)属性

c# - .Net 到 SQL,比较唯一值的最佳方式

c# - "Classes should never perform work involving Dependencies in their constructors."

c# - CaSTLeWindsor LifeStyle.PerWebRequest 表现得像单例

html - 在 HTML5 视频标签中使用属性的正确方法是什么

backbone.js - 为什么模型属性会添加到我的 Backbone.Marionette.ItemView 中?

c# - 有没有办法将英语动词转换为 C# 上的现在时

javascript - 使用站点身份验证 cookie 的摘要进行 CSRF

c# - 比较网站的文本内容

c# - ASP.NET Core 2 - 多个 Azure Redis 缓存服务 DI