asp.net-web-api – 构造函数依赖注入WebApi属性
我一直在寻找WebApi属性的非参数注入选项.
我的问题是使用Structuremap是否真的可以实现这一点? 我一直在谷歌搜索,但继续提出属性注入(我不喜欢使用)或假设的构造函数注入的实现,我到目前为止无法复制. 我选择的容器是Structuremap,但是任何这样的例子就足够了,因为我能够转换它. 有人管过这个吗? 解决方法
对的,这是可能的.你(和大多数人一样)被微软的动作过滤器属性的营销抛出,它们被方便地放入一个单独的类中,但根本不是DI友好的.
解决方案是将操作过滤器属性分为两部分as demonstrated in this post: >一个不包含用于标记控制器和操作方法的行为的属性. 方法是使用IActionFilter测试属性的存在,然后执行所需的行为.可以为动作过滤器提供所有依赖项(通过构造函数),然后在组合应用程序时注入. IConfigProvider provider = new WebConfigProvider(); IActionFilter filter = new MaxLengthActionFilter(provider); config.Filters.Add(filter);
要使用StructureMap进行连接,您需要从DI配置模块返回容器的实例. Application_Start方法仍然是组合根的一部分,因此您可以在此方法中的任何位置使用容器,但它仍然不被视为服务定位器模式.请注意,我没有在此处显示完整的WebApi设置,因为我假设您已经使用WebApi进行了正常的DI配置.如果你需要一个,这是另一个问题. public class DIConfig() { public static IContainer Register() { // Create the DI container var container = new Container(); // Setup configuration of DI container.Configure(r => r.AddRegistry<SomeRegistry>()); // Add additional registries here... #if DEBUG container.AssertConfigurationIsValid(); #endif // Return our DI container instance to the composition root return container; } } public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { // Hang on to the container instance so you can resolve // instances while still in the composition root IContainer container = DIConfig.Register(); AreaRegistration.RegisterAllAreas(); // Pass the container so we can resolve our IActionFilter WebApiConfig.Register(GlobalConfiguration.Configuration,container); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); AuthConfig.RegisterAuth(); } } public static class WebApiConfig { // Add a parameter for IContainer public static void Register(HttpConfiguration config,IContainer container) { config.Routes.MapHttpRoute( name: "DefaultApi",routeTemplate: "api/{controller}/{id}",defaults: new { id = RouteParameter.Optional } ); // Uncomment the following line of code to enable query support for actions with an IQueryable or IQueryable<T> return type. // To avoid processing unexpected or malicious queries,use the validation settings on QueryableAttribute to validate incoming queries. // For more information,visit http://go.microsoft.com/fwlink/?LinkId=279712. //config.EnableQuerySupport(); // Add our action filter config.Filters.Add(container.GetInstance<IMaxLengthActionFilter>()); // Add additional filters here that look for other attributes... } } MaxLengthActionFilter的实现看起来像这样: // Used to uniquely identify the filter in StructureMap public interface IMaxLengthActionFilter : System.Web.Http.Filters.IActionFilter { } public class MaxLengthActionFitler : IMaxLengthActionFilter { public readonly IConfigProvider configProvider; public MaxLengthActionFilter(IConfigProvider configProvider) { if (configProvider == null) throw new ArgumentNullException("configProvider"); this.configProvider = configProvider; } public Task<HttpResponseMessage> ExecuteActionFilterAsync( HttpActionContext actionContext,CancellationToken cancellationToken,Func<Task<HttpResponseMessage>> continuation) { var attribute = this.GetMaxLengthAttribute(filterContext.ActionDescriptor); if (attribute != null) { var maxLength = attribute.MaxLength; // Execute your behavior here (before the continuation),// and use the configProvider as needed return continuation().ContinueWith(t => { // Execute your behavior here (after the continuation),// and use the configProvider as needed return t.Result; }); } return continuation(); } public bool AllowMultiple { get { return true; } } public MaxLengthAttribute GetMaxLengthAttribute(ActionDescriptor actionDescriptor) { MaxLengthAttribute result = null; // Check if the attribute exists on the action method result = (MaxLengthAttribute)actionDescriptor .GetCustomAttributes(typeof(MaxLengthAttribute),false) .SingleOrDefault(); if (result != null) { return result; } // Check if the attribute exists on the controller result = (MaxLengthAttribute)actionDescriptor .ControllerDescriptor .GetCustomAttributes(typeof(MaxLengthAttribute),false) .SingleOrDefault(); return result; } } 并且,不应包含任何行为的属性应如下所示: // This attribute should contain no behavior. No behavior,nothing needs to be injected. [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class,AllowMultiple = false)] public class MaxLengthAttribute : Attribute { public MaxLengthAttribute(int maxLength) { this.MaxLength = maxLength; } public int MaxLength { get; private set; } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net – 实体框架5在保存时停止运行T4模板文件
- asp.net – 我应该为10,000个并发用户实现哪个.net架构用于
- asp.net-mvc – ViewBag vs Model,在MVC.NET中
- 用 C# 写一个 Redis 数据同步小工具
- 如何在ASP.NET中为不同的URL设置不同的超时
- 使T4MVC与ASP.NET 5一起使用
- asp.net – Reflection构成了什么风险? (中等信任)
- asp-classic – 如何从ASP中的字符串中查找特定值
- asp.net – 如何确定用户的浏览器是否可以查看PDF文件
- asp.net – CompositeControl中的DropDownList是否应该记住
- asp.net-mvc – 获取错误参数’nameOrConnection
- 如何使用APDU将PIN验证代码发送到智能卡 – 使用
- .net-4.0 – 从自定义IHttpHandler调用MvcHttpHa
- asp.net-mvc – 任何理由不信任ASP.NET AntiForg
- asp.net-mvc – MVC 4提供的反伪造令牌是为用户“
- asp.net-mvc – 如何在存储库MVC6中注入Applicat
- 动态Linq的逻辑与和逻辑或的条件查询
- asp.net-mvc – MVC 3 RC上的全局过滤器注册错误
- 配置 – ASP.NET Web Api:项目需要SQL Server E
- 如何在ASP.NET PreInit事件中获得控制权?