Как получить доступ к контейнеру Unity в библиотеке классов ActionFilterAttribute?

Итак, у меня есть веб-проект, который использует Unity для внедрения UserRepository для интерфейсов IUserRepository. У меня есть библиотека классов, которая содержит пользовательский файл ActionFilterAttribute. Этот настраиваемый класс атрибутов уже используется во многих действиях. Я хочу добавить к нему некоторый код для проверки значения в базе данных на основе пользователя. Для этого мне нужен доступ к файлу UserRepository. Я мог бы сделать это старомодным способом с использованием операторов и прямым доступом к UserRepository, но я хотел бы использовать DI и разрешить IUserRepository. Как я могу получить доступ к тому, что сеть разрешает IUserRepository, внутри пользовательского класса атрибутов, поскольку ActionFilterAttribute нужен пустой конструктор?


person ScubaSteve    schedule 29.04.2015    source источник
comment
Один подход — eagle081183. wordpress.com/2010/09/21/ . Примечание: я считаю, что то, что вы пытаетесь сделать, - плохая идея, потому что вы вводите синхронные удаленные вызовы в запрос - личное предпочтение.   -  person Alexei Levenkov    schedule 29.04.2015
comment
Предпочитайте жизнь без внедрения зависимостей в атрибуты.   -  person Steven    schedule 29.04.2015
comment
@AlexeiLevenkov Я согласен. Поговорив с некоторыми людьми, мы решили, что есть лучшее место для проверки. Я все еще собираюсь опубликовать ответ, так как решение можно использовать и в другом месте.   -  person ScubaSteve    schedule 29.04.2015


Ответы (3)


Атрибуты — это объекты метаданных. Они не должны участвовать в доступе к базе данных. Используйте отдельную службу для чтения значений атрибутов и, как результат, доступа к базе данных.

person James Lucas    schedule 29.04.2015
comment
Хотя ваше предложение является лучшим дизайном, на самом деле оно не отвечает на мой вопрос. На мой взгляд, это должен быть комментарий к моему вопросу. - person ScubaSteve; 29.04.2015

Таким образом, хотя я решил не выполнять проверку пользователя внутри пользовательского атрибута, решение, разрешающее внедрение внутри пользовательского атрибута, можно использовать в другом месте. У меня было свойство в атрибуте:

public IUserRepository UserRepository { get; set; }

В Web Global.asax.cs я внедрил его через внедрение свойства:

container.RegisterType<NameOfCustomAttribute>(new InjectionProperty("UserRepository", 
                                        new UserRepository(ConfigurationManager.ConnectionStrings["DBName"].ConnectionString)));
person ScubaSteve    schedule 29.04.2015
comment
В вашем ответе отсутствует какое-то волшебство - обычно создание атрибута вообще не проходит через контейнер DI. - person Alexei Levenkov; 29.04.2015
comment
Хм, это довольно большое приложение, в которое я вникаю. Я посмотрю, есть ли что-то, чего мне не хватает. - person ScubaSteve; 29.04.2015
comment
@AlexeiLevenkov Поскольку я новичок в Unity и моем текущем проекте, я поискал в Интернете, чтобы убедиться, что вы правы. Все примеры, которые я нашел, показали, что это делается так, как я. msdn.microsoft.com/en-us/ библиотека/ff660882%28v=pandp.20%29.aspx, geekswithblogs.net/danielggarcia/archive/2014/01/23/, tmont.com/blargh/2010/12/non-magic-property-injection-in-unity - person ScubaSteve; 29.04.2015

Это старый вопрос, но я обнаружил, что вы можете получить доступ к своему разрешению зависимостей в ActionFilterAttribute, используя параметр actionContext следующим образом:

MyFooService myFooService = actionContext.Request.GetDependencyScope().GetService(typeof(MyFooService)) as MyFooService;
person Victor Wilson    schedule 23.01.2019