【问题标题】:Simple Injector property injection on action filter动作过滤器上的简单注入器属性注入
【发布时间】:2012-08-23 07:31:52
【问题描述】:

我要注入的动作过滤器是这样开始的

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 属性为空。

我已经阅读了这篇文章:Simple Injector: Injecting a property in a base class 并关注了答案。我还阅读了此页面中的示例Simple Injector Documentation

我没有注入基类,也许这就是问题所在?

## 更新##

我正在添加更多信息,因为我认为它应该根据 Stevens 回答中所说的内容起作用。

我正在使用 MVC 3 的 NuGet 包。这会将以下内容添加到应用程序中:

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());
}

在我看来,过滤器不是由容器创建的,所以我认为我需要做些别的事情来实现这一点?

【问题讨论】:

  • 如何注册您的UserAuthorisation?你是把它添加到 GlobalFilters 还是 Simple Injector 有一个 filterprovider?
  • 我已经通过全局过滤器添加了它,是我哪里出错了吗?
  • 是的,这就是问题所在。如果 UserAuthorisation 没有通过 Simple Injector 解决,那么 Simple Injector 将不知道您的过滤器,因此无法进行属性注入...
  • 好的很酷,你想把它放到一个答案中吗?可能会显示一个简单的注射器过滤器提供程序的例子,我会接受它(如果它对我有用的话:))。

标签: c# .net asp.net-mvc-3 dependency-injection simple-injector


【解决方案1】:

我选择了 Stevens 的答案作为答案,因为它让我找到了解决方案,我现在正在使用他在 cmets 中提到的命令处理程序。

我做了一个简单的工作来注入我的全局过滤器。

在 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,这可能是一件好事。

【讨论】:

  • 我稍微简化了你的回答。这应该完全相同,但代码更少。如果这不起作用,请随时回滚我的编辑。
  • 谢谢,我再次更新了它,所以一切都在 SimpleInjectorInitializer 类中,所以现在 global.asax.cs 没有任何变化。
  • 注意:RegisterMvcAttributeFilterProvider 现已过时并由RegisterMvcIntegratedFilterProvider 取代:simpleinjector.readthedocs.org/en/latest/…
【解决方案2】:

您正在UserAuthorisation 属性上注册一个初始化程序。然而,初始化器仅在容器本身创建类型时由容器使用。由于属性是由 CLR 创建的,因此初始化程序不会关闭。

SimpleInjector.Integration.Web.Mvc.dll (this NuGet package) 包含一个RegisterMvcAttributeFilterProvider 扩展方法。这将注册一个AttributeFilterProvider,它将执行隐式属性注入(并调用container.InjectProperties 方法)。调用container.RegisterMvcAttributeFilterProvider()后,你会看到这个属性是自动注入的。

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-07
  • 1970-01-01
  • 1970-01-01
  • 2019-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多