非控制器类的依赖注入并调用它们

时间:2017-04-02 21:32:30

标签: .net dependencies core

尝试围绕依赖注入,来自静态类和实例化类的世界。这是我现在拥有的。

[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(),非静态字段需要对象引用”;呼叫。我假设我可以在代码中的任何地方调用此类,而不必创建它的新实例?基本上,如何使用依赖注入从其他类调用方法?

2 个答案:

答案 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中注册。我还在努力研究如何将注册服务(我可以注入)和工作类的新实例(通常包含静态信息)混合在一起,并在它们之间传递信息。