MVC/Unity - Как ввести зависимости в пользовательский FilterAttributes?

Я использовал этот код для смены респондента.

 - (BOOL)textView:(UITextView*) textView shouldChangeTextInRange: (NSRange) range replacementText: (NSString*) text
    {
        if ([text isEqualToString:@"\n"]) {
            //[textView resignFirstResponder];
            //return YES;
            NSInteger nextTag = textView.tag + 1;
            // Try to find next responder
            UIResponder* nextResponder = [self.view viewWithTag:nextTag];
            if (nextResponder) {
                // Found next responder, so set it.
                [nextResponder becomeFirstResponder];
            } else {
                // Not found, so remove keyboard.
                [textView resignFirstResponder];
            }
            return NO; 


            return NO;
        }
        return YES;

    }
7
задан Andrew Cooper 22 March 2012 в 02:43
поделиться

3 ответа

Хорошо, разобрался.

В основном я использовал решение Бена из сообщения в блоге, на которое он указал.

Проблема в том, что Unity ведет себя немного иначе.

Вы не может напрямую вводить зависимости от фильтров, потому что они имеют тип IActionFilter и IExceptionFilter соответственно. Это заставило меня поверить, что они предназначены только для чтения, что не так. Просто Unity необходимо знать явный тип для внедрения.

Итак, в переопределенном методе, представленном в статье, пользователям Unity необходимо запрашивать фильтры для рассматриваемых типов, а затем создавать их.

public UnityActionInvoker(IUnityContainer container, IList<Type> typesToInject)
        {
            _container = container;
            _typesToInject = typesToInject;
        }

] А затем в переопределенном методе сделайте что-нибудь вроде этого:

  var needsInjection = filters.Where(filter => typesToInject.Contains(filter.GetType()));

Немного беспорядочно, но это нужно сделать только один раз, и все будет развязано, как предлагает Бен.

Другая проблема заключается в том, что вы не можете вызвать _контейнер.

2
ответ дан 7 December 2019 в 14:37
поделиться

У вас есть два варианта

Первый вариант - написать собственный ActionInvoker, что не так сложно, как кажется. Прочтите сообщение в блоге . Он специально работает с NInject, но Unity поддерживает внедрение свойств, поэтому вы можете изменить пример для использования Unity.

Это вариант, который объединяет ваш контейнер IoC и не рекомендуется.

public class MyFilter 
{ 
  IMyService MyService {get; set;}

  MyFilter() : MyFilter(MyUnityContainer.Resolve<IMyService>())
  { }

  MyFilter(IMyService service)
  {
    MyService = service;
  }
}
1
ответ дан 7 December 2019 в 14:37
поделиться

Я тоже столкнулся с этой проблемой, и теперь у меня есть рабочее решение. Оно похоже на решение, описанное выше, но с некоторыми небольшими отличиями, а также с добавлением полного кода Unity.

Сначала я буду использовать внедрение свойств по причине, описанной выше, и, как и выше, я буду использовать метод BuildUp в Unity для внедрения свойств в уже созданные фильтры.

Для этого у меня все контроллеры унаследованы от нового настраиваемого базового класса. В этом базовом классе я переопределяю метод CreateActionInvoker, чтобы установить собственный пользовательский ActionInvoker.

Protected Overrides Function CreateActionInvoker() As System.Web.Mvc.IActionInvoker
    Return CustomActionInvoker
End Function

Затем в моем CustomActionInvoker я переопределяю метод GetFilters.

Protected Overrides Function GetFilters(ByVal controllerContext As ControllerContext, ByVal actionDescriptor As ActionDescriptor) As FilterInfo
    Dim info = MyBase.GetFilters(controllerContext, actionDescriptor)

    For Each MyAuthorizationFilter In info.AuthorizationFilters
        MvcApplication.Container.BuildUp(MyAuthorizationFilter.GetType, MyAuthorizationFilter)
    Next

    For Each MyActionFilter In info.ActionFilters
        MvcApplication.Container.BuildUp(MyActionFilter.GetType, MyActionFilter)
    Next

    For Each MyResultFilter In info.ResultFilters
        MvcApplication.Container.BuildUp(MyResultFilter.GetType, MyResultFilter)
    Next

    For Each MyExceptionFilter In info.ExceptionFilters
        MvcApplication.Container.BuildUp(MyExceptionFilter.GetType, MyExceptionFilter)
    Next

    Return info
End Function

Вопреки тому, что было сказано выше, я не обнаружил, что выполнение наращивания внутри цикла For Each вызывало какие-либо проблемы.Я также преодолел исходную проблему, заключающуюся в том, что объект ссылается только через интерфейс, используя одну из других перегрузок метода BuildUp, который принимает System.Type, а также существующий объект.

Теперь, когда все вышеперечисленное сделано, я могу вставлять зависимости прямо в свои фильтры.

Мы очень ценим любые комментарии и мысли.

Ура, Майк

1
ответ дан 7 December 2019 в 14:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: