我喜欢在我的应用程序中使用静态帮助程序类来处理常见的管道事务,例如检查角色,或Razor Html帮助程序和东西......但是你如何在DI世界中这样做?
就像我们想要一个扩展帮助程序来检查用户是否是管理员一样
public static async Task<bool> IsAdmin(this ApplicationUser user)
...
if(user.IsAdmin()){...}
所以pre-core我可以忽略DI并在IsAdmin内部创建一个UserManager做我需要做的任何事情。但现在有没有办法让这些助手中的UserManager才能使用?我能看到的唯一方法是将它注入Controller,然后传递给方法(我觉得很难看)。然后是在Razor视图中尝试执行user.IsAdmin()的问题,我是否需要将UserManager添加到ViewData集合中以使其进入视图标记?
我在这里错过了一些东西吗?
谢谢, 史蒂夫
答案 0 :(得分:1)
那么你在谈论一个跨领域的问题,以及我在ASP.NET Core MVC中解决的横切问题的一种方式是属性(例如[授权])。我认为这是一个优雅的解决方案。
因此,如果我正确理解您的问题,我认为您可以使用动作过滤器解决此问题。 Damien Bod几天前描述了如何使用ActionFilters:https://damienbod.com/2016/09/09/asp-net-core-action-arguments-validation-using-an-actionfilter/。
简而言之,您从ActionFilterAttribute继承并创建自己的名为MyCustomFilter的curstom过滤器。让这个MyCustomFilter通过DI在其构造函数中请求UserManager。然后在控制器中的任何操作方法上面说:
ServiceFilter[typeof(MyCustomFilter)]
在MyCustomFilter中,您可以通过逻辑来检查User是否为IsAdmin,然后相应地采取措施。
现在,我总是使用Microsoft的Unity来通过拦截来处理交叉问题(你可以在这里阅读更多关于它的信息:https://dannyvanderkraan.wordpress.com/2015/09/30/real-world-example-of-adding-auditing-with-dependency-injections-interception/。但是上次我检查的是没有用于asp.net核心的Unity容器但是这篇文章有一篇很棒的文章,关于将它移植到核心:https://dzimchuk.net/post/bring-your-own-di-container-to-aspnet-5-unity。我真的希望我的拦截回来了!非常优雅的解决方案来解决交叉问题。他们正在研究它:https://github.com/unitycontainer/unity/issues/66。交叉...
答案 1 :(得分:1)
首先,如果您刚刚询问如何使用带有di的静态类,我会说您的问题与How to use DI inside a static Method in Asp.net Core rc1重复
但正如我所见,你还有其他问题吗?
但是现在没有办法让这些帮助器中的UserManager 只是用?
是的,有一种方式:Service Locator模式。但这是一种反模式(see this article) 。您应尽可能避免使用此模式。另请参阅github中的discussion。
我能看到的唯一方法是将其注入Controller,然后传递 进入方法(我觉得很难看)
我认为这种方式比你想要的要好。我更喜欢这个。
然后是尝试在Razor中执行user.IsAdmin()的问题 在视图中,我是否需要将UserManager添加到ViewData集合中 将它放入视图标记?
在Aspnet核心中,您可以在视图中注入依赖项,因此您不需要使用ViewData
。只需将UserManager
注入视图,然后将其作为参数传递给方法。看看official docs