将某些东西注入属性类的最佳方法是什么?
严格来说,我们不能使用依赖注入将依赖注入到属性中。 Attributes are for metadata 不是行为。 [AttributeSpecification()] 通过禁止引用类型作为参数来鼓励这一点。
您可能正在寻找use an attribute and a filter together, and then to inject dependencies into the filter。属性添加元数据,决定是否应用过滤器,过滤器接收注入的依赖。
如何对属性使用依赖注入?
这样做的理由很少。
也就是说,如果您打算注入属性,则可以使用 ASP.NET Core MVC IApplicationModelProvider。框架将依赖传递给提供者的构造函数,提供者可以将依赖传递给属性的属性或方法。
在您的 Startup 中,注册您的提供商。
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 System.Linq;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Microsoft.AspNetCore.Mvc.Routing;
public class MyApplicationModelProvider : IApplicationModelProvider
{
private IUrlHelperFactory _urlHelperFactory;
// constructor injection
public MyApplicationModelProvider(IUrlHelperFactory urlHelperFactory)
{
_urlHelperFactory = urlHelperFactory;
}
public int Order { get { return -1000 + 10; } }
public void OnProvidersExecuted(ApplicationModelProviderContext context)
{
foreach (var controllerModel in context.Result.Controllers)
{
// pass the depencency to controller attibutes
controllerModel.Attributes
.OfType<MyAttribute>().ToList()
.ForEach(a => a.UrlHelperFactory = _urlHelperFactory);
// pass the dependency to action attributes
controllerModel.Actions.SelectMany(a => a.Attributes)
.OfType<MyAttribute>().ToList()
.ForEach(a => a.UrlHelperFactory = _urlHelperFactory);
}
}
public void OnProvidersExecuting(ApplicationModelProviderContext context)
{
// intentionally empty
}
}
使用可以接收依赖项的公共设置器创建一个属性。
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";
}
}
上面演示了一种方法,对于罕见的用例,您可以将依赖项注入属性。如果您找到这样做的正当理由,请将其发布在 cmets 中。