Я делал это некоторое время назад на ASP. NET MVC проекте с Ninject для DI. Комментарий Эндрю от 10 апреля по поводу его собственного ответа - верное направление, но вот как это может выглядеть для вас (пример использует Ninject, но вы можете адаптироваться к любому используемому вами DI).
- Технически ваш атрибут в порядке, но на практике вы должны определить атрибут, который не имеет поведения , который просто связан с фильтром , где поведение живет. Я адаптировал ваш, чтобы соответствовать этой лучшей практике следующим образом:
public class LoggerAttribute : ActionFilterAttribute {}
public class LoggerFilter : IActionFilter
{
private readonly IHttpLogService _httpLogService;
private readonly ILogService _logService;
public LoggerAttribute(IHttpLogService httpLogService, ILogService logService)
{
_httpLogService = httpLogService;
_logService = logService;
}
// Code removed for brevity
}
В Global.asax.cs вам необходимо создать экземпляр службы (или получить ее на заводе, если она у вас есть).
namespace MyApp.Web
{
public class MvcApplication : NinjectHttpApplication
{
private static readonly IHttpLogService _httpLogService = someFactory.GetLogService();
// Or if you don't use a factory
// private static readonly IHttpLogService _httpLogService = new MyLogServiceImplementation();
private static readonly ILogService _logService = new MyLogService();
// Other stuff like OnApplicationStarted() here
protected override IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.BindFilter<LoggerFilter>(FilterScope.Action, 0)
.WhenActionMethodHas<LoggerAttribute>()
.WithConstructorArgument("httpLogService", _httpLogService)
.WithConstructorArgument("logService", _logService);
}
}
}
В ключевой части мы .WithConstructorArgument()
и этот синтаксис зависит от пакета DI.
Также см. мой более подробный ответ здесь относительно аналогичного вопроса / структуры.