Простая инъекция свойства Injector в фильтр действий

Фильтр действий, в который я хочу внедрить, начинается так:

public class UserAuthorisation : AuthorizeAttribute
{
    public IWcfClientProxy<IAppFrameworkServiceChannel>
        FrameworkServiceProxy { get; set; }

Я настроил свой контейнер следующим образом:

container.Register<IWcfClientProxy<IAppFrameworkServiceChannel>>(
    ()=> new WcfClientProxy<IAppFrameworkServiceChannel>());

container.RegisterInitializer<UserAuthorisation>(handler =>
{
    handler.FrameworkServiceProxy = container
       .GetInstance<IWcfClientProxy<IAppFrameworkServiceChannel>>();
});

Когда я запускаю это, свойство FrameworkServiceProxy имеет значение null.

Я прочитал это сообщение: Simple Injector: внедрение свойства в базовый класс и последовал ответу. Я также прочитал пример на этой странице Документация по простому инжектору.

Я не ввожу в базовый класс, и, может быть, проблема в этом?

## ОБНОВИТЬ ##

Я добавляю больше информации, так как думаю, что это должно работать на основе того, что было сказано в ответе Стивенса.

Я использую пакет NuGet для MVC 3. Это добавляет в приложение следующее:

public static class SimpleInjectorInitializer
{
    /// <summary>Initialize the container and register it as MVC3 Dependency Resolver.</summary>
    public static void Initialize()
    {
        var container = new Container();
        InitializeContainer(container);
        container.RegisterMvcControllers(Assembly.GetExecutingAssembly());
        container.RegisterMvcAttributeFilterProvider();
        container.Verify();
        DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
    }

    private static void InitializeContainer(Container container)
    {
        container.Register<IWcfClientProxy<IAppFrameworkServiceChannel>>(() => new WcfClientProxy<IAppFrameworkServiceChannel>());
        container.RegisterInitializer<UserAuthorisation>(handler =>
            {
                handler.FrameworkServiceProxy = container.GetInstance<IWcfClientProxy<IAppFrameworkServiceChannel>>();
            });
    }

Это включает в себя container.RegisterMvcAttributeFilterProvider();, который, как я теперь понимаю, должен регистрировать поставщика фильтров и должен означать, что фильтры создаются через контейнер (это понимание может быть неправильным), а затем автоматически подключаются свойства.

Мой фильтр зарегистрирован в Global.asax.cs следующим образом:

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new HandleErrorAttribute());
    filters.Add(new UserAuthorisation());
}

Мне кажется, что фильтр не создается контейнером, поэтому я думаю, что мне нужно сделать что-то еще, чтобы это произошло?


person David McLean    schedule 23.08.2012    source источник
comment
Как вы регистрируете свой UserAuthorisation? Вы добавляете его в GlobalFilters или в Simple Injector есть поставщик фильтров?   -  person nemesv    schedule 23.08.2012
comment
Я добавил его через глобальные фильтры, я ошибся?   -  person David McLean    schedule 23.08.2012
comment
Да, это проблема. Если UserAuthorisation не разрешается с помощью Simple Injector, то Simple Injector не будет знать о вашем фильтре, поэтому не сможет выполнить инъекцию свойств...   -  person nemesv    schedule 23.08.2012
comment
ОК, круто, вы хотите поместить это в ответ, возможно, показав пример простого поставщика фильтра инжектора, и я приму его (ну, если это сработает для меня :)).   -  person David McLean    schedule 23.08.2012


Ответы (2)


Вы регистрируете инициализатор для своего атрибута UserAuthorisation. Однако инициализаторы используются контейнером только тогда, когда тип создается самим контейнером. Поскольку атрибуты создаются средой CLR, инициализатор не срабатывает.

SimpleInjector.Integration.Web.Mvc.dll (этот пакет NuGet) содержит метод расширения RegisterMvcAttributeFilterProvider. Это зарегистрирует AttributeFilterProvider, который выполнит неявную инъекцию свойства (и вызовет метод container.InjectProperties). После вызова container.RegisterMvcAttributeFilterProvider() вы увидите, что это свойство внедряется автоматически.

person Steven    schedule 23.08.2012

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

Я применил простой обходной путь, чтобы ввести мои глобальные фильтры.

В App_Start\SimpleInjectorInitializer.cs я добавил RegisterGlobalFilters следующим образом:

public static void RegisterGlobalFilters(GlobalFilterCollection filters, Container container)
{
    //Add simple injector resolved types.
    filters.Add(container.GetInstance<UserAuthorisation>());
}

И в методе Initialize я добавил это RegisterGlobalFilters(GlobalFilters.Filters, container);

Полный метод выглядит так:

/// <summary>Initialize the container and register it as MVC3 Dependency Resolver.</summary>
public static void Initialize()
{
    var container = new Container();
    InitializeContainer(container);
    container.RegisterMvcControllers(Assembly.GetExecutingAssembly());
    container.RegisterMvcAttributeFilterProvider();
    container.Verify();
    DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));

    RegisterGlobalFilters(GlobalFilters.Filters, container);
}

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

Это означает, что вам не нужно изменять global.asax.cs, что, возможно, хорошо.

person David McLean    schedule 24.08.2012
comment
Я немного упростил ваш ответ. Это должно делать то же самое, но с меньшим количеством кода. Не стесняйтесь отменить мою правку, если это не сработает. - person Steven; 24.08.2012
comment
Спасибо, я снова обновил его, так что все находится в классе SimpleInjectorInitializer, поэтому теперь никаких изменений в global.asax.cs. - person David McLean; 24.08.2012
comment
Примечание. RegisterMvcAttributeFilterProvider теперь устарело и заменено на RegisterMvcIntegratedFilterProvider: simpleinjector.readthedocs.org /ru/последние/ - person NoOne; 24.06.2015