17

I have a Web API controller that has some resources DI'd. Out of later necessity I have added an MVC controller, now I need same resources DI'd there as well. Here is my original configuration:

    [assembly: WebActivator.PostApplicationStartMethod(typeof(CineplexSearch.App_Start.SimpleInjectorWebApiInitializer), "Initialize")]

namespace CineplexSearch.App_Start
{
    using System.Web.Http;
    using SimpleInjector;
    using SimpleInjector.Integration.WebApi;

    public static class SimpleInjectorWebApiInitializer
    {
        /// <summary>Initialize the container and register it as Web API Dependency Resolver.</summary>
        public static void Initialize()
        {
            var container = new Container();
            container.Options.DefaultScopedLifestyle = new WebApiRequestLifestyle();

            InitializeContainer(container);

            container.RegisterWebApiControllers(GlobalConfiguration.Configuration);

            container.Verify();

            GlobalConfiguration.Configuration.DependencyResolver =
                new SimpleInjectorWebApiDependencyResolver(container);
        }

        private static void InitializeContainer(Container container)
        {
            container.Register<ICachingManager, CachingManager>(Lifestyle.Transient);
            container.Register<IDataAccessLayer, DataAccessLayer>(Lifestyle.Transient);
        }
    }
}

Can I register DI for MVC Controller in the same place as well? Can I reuse the container?

Update: I must be close, but now I get an error in the Web API controller that I need a parameterless constructor; I tried adding it, but then nothing gets injected of course

public static class SimpleInjectorWebApiInitializer
{
    /// <summary>Initialize the container and register it as Web API Dependency Resolver.</summary>
    public static void Initialize()
    {
        var container = new Container();
        container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();

        InitializeContainer(container);

        container.RegisterWebApiControllers(GlobalConfiguration.Configuration);
        container.RegisterMvcControllers(Assembly.GetExecutingAssembly());

        container.Verify();

        //GlobalConfiguration.Configuration.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);
        DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
    }

    private static void InitializeContainer(Container container)
    {
        container.Register<ICachingManager, CachingManager>(Lifestyle.Transient);
        container.Register<IDataAccessLayer, DataAccessLayer>(Lifestyle.Transient);
    }
}

3 Answers 3

16

Can I reuse the container?

Yes you can, and you should. Every app domain should typically have one container instance.

The MVC integration documentation of the Simple Injector documentation explains that you should set the MVC DependencyResolver as follows:

DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));

To make things easier however, your should register the WebRequestLifestyle as DefaultScopedLifestyle:

container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();

This will work for Web API as well, since you are solely running Web API from within IIS.

So you need to configure both the DependencyResolvers.

Sign up to request clarification or add additional context in comments.

7 Comments

Thanks for quick reply, I almost have it working, can you please see my update?
@FailedUnitTest you need both the dependency resolvers. So the Web API dependency resolver as well.
Just so I completely understand, we should use both .RegisterMvcControllers() and RegisterWebApiControlers() as well as both System.Web.Mvc.DependencyResolver(new SimpleInjectorDependencyResolver(container)) and GlobalConfiguration.Configuration.DependencyResolver(new SimpleInjectorWebApiDependencyResolver(container))?
@Dr.Zim: If you use both Web API and MVC: yes.
Thank you @Dr.Zim. By your comment, i understood the whole answer.
|
3

I would like to add my two cents because after reading Steven's answer and the comments below it I still got some errors. Eventually this had to do with the order in which things are getting configured.

protected void Application_Start()
{
    //set the default scoped lifestyle
    Container container = new Container();
    container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();

    ...
    //do class registration here. I did it with Scoped lifestyle
    ...
    //Let the SimpleInjector.Intergration packages register the controllers.       
    container.RegisterWebApiControllers(GlobalConfiguration.Configuration);
    container.RegisterMvcControllers(Assembly.GetExecutingAssembly());

    AreaRegistration.RegisterAllAreas();
    //This must be here because we first need to do above before registering the web api. See WebApiConfig code.
    GlobalConfiguration.Configure(WebApiConfig.Register);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);

    //don't set the resolver here, do it in WebApiConfig.Register()
    //DependencyResolver.SetResolver(new SimpleInjectorWebApiDependencyResolver(container));
    DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
    container.Verify(SimpleInjector.VerificationOption.VerifyAndDiagnose);
}

WebApiConfig:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API routes
        config.MapHttpAttributeRoutes();
        //set the webApi resolver here!
        config.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(DependencyInjectionCoreSetup._Container);
        //then the rest..
        var route = config.Routes.MapHttpRoute(
        ....
    }
}

1 Comment

DependencyInjectionCoreSetup?
1

Also be aware that the WebRequestLifestyle() is obsolete at the time . You can use instead:

//...

container.Options.DefaultScopedLifestyle = new SimpleInjector.Lifestyles.AsyncScopedLifestyle();

//...

1 Comment

WebRequestLifestyle(bool) is obsolete. WebRequestLifestyle() is not obsolete. simpleinjector.org/ReferenceLibrary/html/… The recommendation is to use AsyncScopedLifestyle in applications that solely consist of a Web API (or other asynchronous technologies such as ASP.NET Core) and use WebRequestLifestyle for applications that contain a mixture of Web API and MVC. simpleinjector.readthedocs.io/en/latest/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.