尝试围绕依赖注入,来自静态类和实例化类的世界。这是我现在拥有的。
[SomeFilter]
public class AController : Controller
{
private readonly IOptions<AppSettings> _appSettings;
public AController(IOptions<AppSettings> appSettings)
{
_appSettings = appSettings;
}
// GET: /characters/
public IActionResult Index()
{
//do something
}
立即调用SomeFilter,并执行此操作:
public class SomeFilter: ActionFilterAttribute, IActionFilter
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
OtherClass.RunMe();
}
}
OtherClass看起来像这样:
public class OtherClass
{
private readonly IOptions<AppSettings> _appSettings;
public OtherClass(IOptions<AppSettings> appSettings)
{
_appSettings = appSettings;
}
public RunMe()
{
//do something
}
我还在Startup.cs中将OtherClass注册为service.Singleton。
我收到一条错误,指出:“对于OtherClass.RunMe(),非静态字段需要对象引用”;呼叫。我假设我可以在代码中的任何地方调用此类,而不必创建它的新实例?基本上,如何使用依赖注入从其他类调用方法?
答案 0 :(得分:0)
您无法在过滤器上进行构造函数注入。这都是关于运行时的顺序。当您尝试注入构造函数时,您的IoC容器此刻无法访问。你应该使用property / setter injection。
我更喜欢使用structuremap容器来执行此操作。因为structuremap非常容易应用任何类型的注入。例如,当你有一个像这样的过滤器注册表
$this->load->library('session')
您可以在global.asax(prefer)或其中一个启动类中注册它。 示例app_Start方法。
public class ActionFilterRegistry : Registry
{
public ActionFilterRegistry(Func<IContainer> containerFactory)
{
For<IFilterProvider>().Use(
new StructureMapFilterProvider(containerFactory));
Policies.SetAllProperties(x =>
x.Matching(p =>
p.DeclaringType.CanBeCastTo(typeof(ActionFilterAttribute)) &&
p.DeclaringType.Namespace.StartsWith("YourNameSpace") &&
!p.PropertyType.IsPrimitive &&
p.PropertyType != typeof(string)));
}
}
然后您可以使用任何注射过滤器。但要注意你不应该像你一样使用构造函数注入。
答案 1 :(得分:0)
我找到了一种使用
注入过滤器的方法[ServiceFilter(typeof(MyFilter))]
而不仅仅是
[MyFilter]
并在过滤器的
中(ActionExecutingContext context)
{
var controller = context.Controller as Controller.
controller.whateverIneed
}
这现在为我提供了过滤器中我需要的东西。我还意识到,我不能删除使用new
创建对其他类的引用的需要,因为我的印象是Core的依赖关系是“不再new
”。这进入了我仍然掌握的核心基础。
我最终做的是创建一些可以完成某些工作的新类,但它们被设置为 services 并在startup.cs中注册。我还在努力研究如何将注册服务(我可以注入)和工作类的新实例(通常包含静态信息)混合在一起,并在它们之间传递信息。