Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何对属性使用依赖项注入?_C#_.net_Asp.net Mvc_Dependency Injection - Fatal编程技术网

C# 如何对属性使用依赖项注入?

C# 如何对属性使用依赖项注入?,c#,.net,asp.net-mvc,dependency-injection,C#,.net,Asp.net Mvc,Dependency Injection,在我正在创建的一个MVC项目中,我有以下requireCommissionAttribute,用于执行任何需要特定权限的操作(本例中对其进行了简化): 因此,这显然存在一个问题,即我的authorize属性依赖于我创建的ASPNETAuthorizationService。我不能使用构造函数,因为属性是编译时检查的 值得一提的是,我正在使用我自己制作的小IoC,但它还不支持属性注入。当然,如果我真的选择了财产注入方式,我必须为它添加支持(我必须对此进行一些研究) 向属性类中注入内容的最佳方法是什

在我正在创建的一个MVC项目中,我有以下
requireCommissionAttribute
,用于执行任何需要特定权限的操作(本例中对其进行了简化):

因此,这显然存在一个问题,即我的authorize属性依赖于我创建的
ASPNETAuthorizationService
。我不能使用构造函数,因为属性是编译时检查的

值得一提的是,我正在使用我自己制作的小IoC,但它还不支持属性注入。当然,如果我真的选择了财产注入方式,我必须为它添加支持(我必须对此进行一些研究)


向属性类中注入内容的最佳方法是什么?

我最初认为这是不可能的,但我得到了纠正。以下是Ninject的一个示例:

更新2016-10-13 到目前为止,这是一个相当老的问题,框架已经发生了相当大的变化。要基于特定属性的存在向特定筛选器添加绑定,请使用以下代码:

// LogFilter is applied to controllers that have the LogAttribute
this.BindFilter<LogFilter>(FilterScope.Controller, 0)
     .WhenControllerHas<LogAttribute>()
     .WithConstructorArgument("logLevel", Level.Info);
 
// LogFilter is applied to actions that have the LogAttribute
this.BindFilter<LogFilter>(FilterScope.Action, 0)
     .WhenActionHas<LogAttribute>()
     .WithConstructorArgument("logLevel", Level.Info);
 
// LogFilter is applied to all actions of the HomeController
this.BindFilter<LogFilter>(FilterScope.Action, 0)
     .WhenControllerTypeIs<HomeController>()
     .WithConstructorArgument("logLevel", Level.Info);
 
// LogFilter is applied to all Index actions
this.BindFilter(FilterScope.Action, 0)
     .When((controllerContext,  actionDescriptor) =>
                actionDescriptor.ActionName == "Index")
     .WithConstructorArgument("logLevel", Level.Info);
//LogFilter应用于具有LogFilter属性的控制器
此.BindFilter(FilterScope.Controller,0)
.WhenControllerHas()
.带有Constructor参数(“logLevel”,Level.Info);
//LogFilter应用于具有LogFilter属性的操作
此.BindFilter(FilterScope.Action,0)
.WhenActionHas()
.带有Constructor参数(“logLevel”,Level.Info);
//LogFilter应用于HomeController的所有操作
此.BindFilter(FilterScope.Action,0)
.当控制器类型为()时
.带有Constructor参数(“logLevel”,Level.Info);
//LogFilter应用于所有索引操作
此.BindFilter(FilterScope.Action,0)
.When((controllerContext,actionDescriptor)=>
actionDescriptor.ActionName==“索引”)
.带有Constructor参数(“logLevel”,Level.Info);
这符合原则,即您应该将操作过滤器的逻辑与自定义属性类分开

向属性中注入比以前更多的值。不过,将动作过滤器与属性分离确实是最好的方法

向属性类中注入内容的最佳方式是什么

严格地说,我们不能使用依赖项注入将依赖项注入到属性中。不是行为<代码>[AttributeSpecification()]通过禁止引用类型作为参数来鼓励这一点

你可能要找的是。该属性添加元数据,元数据决定是否应用过滤器,过滤器接收注入的依赖项

using System;
using Microsoft.AspNetCore.Mvc.Routing;

public sealed class MyAttribute : Attribute
{
    private string _someParameter;

    public IUrlHelperFactory UrlHelperFactory { get; set; }

    public MyAttribute(string someParameter)
    {
        _someParameter = someParameter;
    }
}
如何对属性使用依赖项注入

这样做的理由很少

这就是说,如果您打算注入属性,可以使用ASP.NET核心MVC
IAApplicationModelProvider
。框架将依赖项传递给提供者的构造函数,提供者可以将依赖项传递给属性的属性或方法

在启动时,注册提供商

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.TryAddEnumerable(ServiceDescriptor.Transient
            <IApplicationModelProvider, MyApplicationModelProvider>());

        services.AddMvc();
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseMvc();
    }
}
将属性应用于控制器或操作

using Microsoft.AspNetCore.Mvc;

[Route("api/[controller]")]
[MyAttribute("SomeArgument")]
public class ValuesController : Controller
{
    [HttpGet]
    [MyAttribute("AnotherArgument")]
    public string Get()
    {
        return "Foobar";
    }
}

对于罕见的用例,上面演示了一种将依赖项注入属性的方法。如果你找到了这样做的正当理由,请在评论中发表

@ShaunLuttin:请随意添加您自己的答案和代码示例以及解释。我会投赞成票。@ShaunLuttin:这是一个有趣的方法。我给了你一票,就像我答应的那样。而且,在考虑了一会儿之后,我意识到我的答案需要更新。谢谢你引起我的注意。研究让我发现属性不应该包含行为,只应该包含数据。当你写“将动作过滤器的逻辑与自定义属性类分开”时,这就是你的意思吗?@ShaunLuttin:是的,这就是我的意思。该属性只是一个POCO,用于保存元数据。实现
IActionFilter
接口的类是一个包含行为的独立类。这很有意义。在此基础上,我更新了我的答案,以强调注入属性和注入与属性相关的过滤器之间的区别。非常感谢-我的用例(我不确定它是否正确)是将依赖项传递到验证器属性。我们使用属性来验证我们的模型,一些验证逻辑需要共享逻辑,我们将其隔离到注入的服务中。
using System;
using Microsoft.AspNetCore.Mvc.Routing;

public sealed class MyAttribute : Attribute
{
    private string _someParameter;

    public IUrlHelperFactory UrlHelperFactory { get; set; }

    public MyAttribute(string someParameter)
    {
        _someParameter = someParameter;
    }
}
using Microsoft.AspNetCore.Mvc;

[Route("api/[controller]")]
[MyAttribute("SomeArgument")]
public class ValuesController : Controller
{
    [HttpGet]
    [MyAttribute("AnotherArgument")]
    public string Get()
    {
        return "Foobar";
    }
}