我正在尝试完全理解依赖注入。我正在定义一个过滤器,想从配置文件中读取。在过滤器内部实例化配置是一种更好的做法,还是可以在全局(例如在启动过程中)实例化此配置?如果是这样,那么有关如何执行操作的任何指针?
public class CompanyFilter : ActionFilterAttribute
{
string _ERPUrl;
public CompanyFilter(IConfiguration iconfiguration)
{
ERPUrl = iconfiguration.GetSection("AppSettings").GetSection("ERPUrl").Value;
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.Controller is Controller controller)
controller.ViewBag.ERPUrl = _ERPUrl;
//filterContext.Controller.ViewBag.Company = "Test";
}
}
启动类
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
....
控制器
namespace Projects.Controllers
{
[CompanyFilter]
public class HomeController : Controller
{
....
产生以下错误。
Controllers \ HomeController.cs(14,6):错误CS7036:没有提供与'CompanyFilter.CompanyFilter(IConfiguration)'所需的形式参数'iconfiguration'相对应的参数
答案 0 :(得分:0)
我建议您使用IOptions<T>
从文件中检索配置,而该文件具有.Net Core支持的所有优点。您可以查看操作方法here。
另外,要将其注入到可靠的注入解析器中,请在services.AddTransient(p => new MyService(mySettings));
函数中添加ConfigureServices()
作为瞬态或作用域或单例(确定哪个更适合您)。
如果您坚持使用IConfiguration
来检索配置并解决所遇到的问题,则应像这样IConfiguration
注入services.AddSingleton(Configuration);
实例。希望这能解决您的问题。
答案 1 :(得分:0)
根据此处的一些反馈,通过将其添加到Startup.cs,以下操作是可行的。
services.AddMvc(options => {
options.Filters.Add(new ERPFilter(Configuration));
}
可以根据以上几点对网址进行分解,以提高性能。
url = ...
services.AddMvc(options => {
options.Filters.Add(new ERPFilter(url));
}
答案 2 :(得分:0)
要根据其他人和我自己昨天提供的评论提供答案,建议将IOptions<T>
注入到您的过滤器或任何其他需要注入配置数据的对象中。
您可以像这样将ERP设置添加到appSettings.json文件中
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*",
"Erp": {
"Url": "https://localhost"
}
}
要将设置注入依赖项,您必须通过ConfigureServices
注册它,您还会注意到CompanyFilter
是通过IServiceCollection
添加到AddTransient
的,这是为了允许ServiceFilterAttribute
在以后的阶段进行解析,并注入过滤器具有的所有依存关系。
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.Configure<ErpSettings>(Configuration.GetSection("Erp"));
services.AddTransient<CompanyFilter>();
}
要将过滤器应用于控制器操作,请使用ServiceFilterAttribute(Type)`
[HttpGet]
[ServiceFilter(typeof(CompanyFilter))]
public ActionResult<IEnumerable<string>> Get()
{
return new string[] { ViewBag.ERPUrl };
}
在上面的代码中,您将看到我正在返回ViewBag.ERPUrl,这是因为您的ComapnyFilter
已覆盖OnActionExecuting
,该OnActionExecuted
在调用操作之前已执行,而CompanyFilter
在您的操作完成之后且响应返回给调用方之前将被调用。
IOptions<ErpSettings>
的外观如下,您会注意到构造函数现在接受public class CompanyFilter : ActionFilterAttribute
{
private readonly ErpSettings erpSettings;
public CompanyFilter(IOptions<ErpSettings> erpSettings)
{
this.erpSettings= erpSettings.Value;
}
public override void OnActionExecuting(ActionExecutingContext context)
{
if (context.Controller is Controller controller)
controller.ViewBag.ERPUrl = erpSettings.Url;
}
}
{{1}}
所有这些完成后,这就是响应