Не удалось внедрить атрибут Autofac в атрибуты

Я нашел несколько вопросов по этому поводу, но они, как правило, указывают на точную документацию, которой я следую... но она все еще не работает.

Я создаю довольно простой сайт ASP.NET MVC 4, и я планирую использовать ведение журнала на основе ActionFilterAttribute. У меня есть класс DataAccessProvider, который открывает транзакции с базой данных и предоставляет экземпляры единиц работы, и я пытаюсь внедрить его в атрибут фильтра.

В документации говорится, что достаточно просто вызвать RegisterFilterProvider() и убедиться, что соответствующие типы зарегистрированы. Там конкретно написано, что атрибут прописывать не надо, но я пробовал и с ним и без. Мой код в настоящее время выглядит примерно так:

var builder = new ContainerBuilder();
builder.RegisterControllers(Assembly.GetExecutingAssembly());

builder.Register(x => new EntityAccessProvider())
    .As<IDataAccessProvider>()
    .InstancePerHttpRequest();

builder.RegisterType<DebugLogAttribute>().PropertiesAutowired();
// ^ I've tried it with and without this line

builder.RegisterFilterProvider();
var container = builder.Build();

DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

Затем пример в документах просто помещает свойство в фильтр, поэтому я сделал то же самое:

public class DebugLogAttribute : ActionFilterAttribute
{
    private IDataAccessProvider DataAccess { get; set; }

    public override void OnActionExecuting(ActionExecutingContext filterContext) { ... }
    public override void OnActionExecuted(ActionExecutedContext filterContext) { ... }
}

Документы говорят, что это все, что требуется - даже не конструктор для внедрения; это делается путем внедрения свойства. Однако, когда я запускаю этот код, свойство DataAccess всегда равно null; Autofac, кажется, игнорирует это. Я знаю, что регистрация работает правильно, потому что она правильно вводит EntityAccessProvider в мои контроллеры, но не работает для атрибутов. Что мне не хватает?


person anaximander    schedule 28.07.2013    source источник


Ответы (2)


Чтобы инъекция работала, ваше свойство типа IDataAccessProvider должно быть общедоступным. Вы все еще можете пометить DebugLogAttribute, IDataAccessProvider и их реализацию как внутреннюю, если хотите.

[DebugLogAttribute]
public class HOmeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }
}

internal class DebugLogAttribute : ActionFilterAttribute
{
    public IDataAccessProvider DataAccess { get; set; }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        Debugger.Break();
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        Debugger.Break();
    }
}

internal interface IDataAccessProvider {}

internal class DataAccessProvider:IDataAccessProvider {}
person Nenad    schedule 28.07.2013
comment
Упс... совсем пропустил. Спасибо! - person anaximander; 28.07.2013
comment
Спасибо за ваше решение :) - person Redplane; 04.06.2016

У меня была такая же проблема в ядре asp dotnet, но текущее решение (делающее его общедоступным), похоже, не работает. Что мне кажется странным, так это то, что комментарий ниже касается веб-API, но я использую обычный ASP.NET Core MVC (MVC6). Так что, если у кого-то есть такая же проблема, попробуйте решение ниже.

https://docs.autofac.org/en/latest/integration/webapi.html#standard-web-api-filter-attributes-are-singletons

В отличие от поставщика фильтров в MVC, поставщик в Web API не позволяет указать, что экземпляры фильтра не должны кэшироваться. Это означает, что все атрибуты фильтра в веб-API фактически являются одноэлементными экземплярами, которые существуют на протяжении всего времени существования приложения.

public override async Task OnActionExecutionAsync(
            ActionExecutingContext context,
            ActionExecutionDelegate next)
        {
            MyService = context.HttpContext.
                               RequestServices.GetService(typeof(IMyService)) as IMyService;
        }
person MichaelChan    schedule 08.04.2019