Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

I have read this post: Simple Injector: Injecting a property in a base class and followed the answer. I have also read example in this page Simple Injector Documentation.

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:

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

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 ?

like image 327
David McLean Avatar asked Aug 23 '12 07:08

David McLean


People also ask

What is simple injection?

A Simple Injector is an easy, flexible, and fast dependency injection library. The purpose of a Simple Injector is to provide . NET application developers with an easy, flexible, and fast Inversion of Control library that uses best practices to steer developers to success.

Can we inject the dependency to individual action method of the controller?

You can take advantage of the ServiceFilter attribute to inject dependencies in your controller or your controller's action methods.


1 Answers

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.

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:

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

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.

like image 178
David McLean Avatar answered Oct 21 '22 12:10

David McLean