简体   繁体   English

在动作过滤器上进行简单的Injector属性注入

[英]Simple Injector property injection on action filter

The action filter I want to inject into starts like this 我要注入的动作过滤器是这样启动的

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

I have setup my container like this: 我已经像这样设置了我的容器:

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

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

When I run this the FrameworkServiceProxy property is null. 当我运行此FrameworkServiceProxy属性为null。

I have read this post: Simple Injector: Injecting a property in a base class and followed the answer. 我已经阅读了这篇文章: Simple Injector:在基类中注入一个属性,并遵循答案。 I have also read example in this page Simple Injector Documentation . 我还在本页Simple Injector文档中阅读了示例。

I am not injecting into a base class and maybe that is the issue? 我没有注入基类,也许这是问题所在吗?

## UPDATE ## ##更新##

I am adding more information as I think it should be working from what has been said in Stevens answer. 我正在添加更多信息,因为我认为它应该根据史蒂文斯答案中所说的起作用。

I am using the NuGet package for MVC 3. This adds the following to the application: 我正在为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>>();
            });
    }

This includes the container.RegisterMvcAttributeFilterProvider(); 这包括container.RegisterMvcAttributeFilterProvider(); that as I now understand it should register a filter provider and should mean that filters are created through the container (this understanding might be wrong) and then properties are automatically wired-up. 据我所知,它应该注册一个过滤器提供程序,并且应该意味着通过容器创建过滤器(这种理解可能是错误的),然后属性会自动连接起来。

My filter is registered in the Global.asax.cs like so: 我的过滤器像这样在Global.asax.cs中注册:

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

It seems to me that the filter is not being created by the container so I think I need to do something else to get that to happen ? 在我看来,过滤器不是由容器创建的,所以我认为我需要做其他事情才能使这种情况发生?

I have selected Stevens answer as the answer as it got me to a solution and I am now using the command handler that he mentioned in the comments. 我选择了Stevens答案作为答案,因为它为我提供了解决方案,现在我正在使用他在评论中提到的命令处理程序。

I have put a simple work around in to get my global filters injected. 我进行了一个简单的工作来注入全局过滤器。

In the App_Start\\SimpleInjectorInitializer.cs I have added RegisterGlobalFilters like this: 在App_Start \\ SimpleInjectorInitializer.cs中,我添加了RegisterGlobalFilters如下所示:

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

And in the Initialize method I have added this RegisterGlobalFilters(GlobalFilters.Filters, container); Initialize方法中,我添加了此RegisterGlobalFilters(GlobalFilters.Filters, container);

The complete method looks like this: 完整的方法如下所示:

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

As I said very simple. 正如我所说的很简单。 Just get my instances from simple injector and then add them to the global list, I am sure there are better ways to do this. 只需从简单的注射器中获取我的实例,然后将它们添加到全局列表中,我相信有更好的方法可以做到这一点。

This way does mean you do not need to change the global.asax.cs which is possibly a good thing. 这种方式确实意味着您不需要更改global.asax.cs,这可能是一件好事。

You are registering an initializer on your UserAuthorisation attribute. 您正在您的UserAuthorisation属性上注册一个初始化程序。 Initializers however, are only used by the container when a type is created by the container itself. 但是,初始化器仅在由容器本身创建类型时才由容器使用。 Since attributes are created by the CLR, the initializer won't go off. 由于属性是由CLR创建的,因此初始化程序不会关闭。

The SimpleInjector.Integration.Web.Mvc.dll ( this NuGet package ) contains a RegisterMvcAttributeFilterProvider extension method. SimpleInjector.Integration.Web.Mvc.dll( 此NuGet包 )包含RegisterMvcAttributeFilterProvider扩展方法。 This will register an AttributeFilterProvider that will do implicit property injection (and call into the container.InjectProperties method). 这将注册一个AttributeFilterProvider ,它将进行隐式属性注入(并调用container.InjectProperties方法)。 After calling container.RegisterMvcAttributeFilterProvider() , you will see that this property is injected automatically. 调用container.RegisterMvcAttributeFilterProvider() ,您将看到该属性被自动注入。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM