markoverflow markoverflow - 2 months ago 42
ASP.NET (C#) Question

Dependency Injection on Global.asax compilation error

I'm having compilation error when calling my service in global.asax. Im using UnityMvc as my DI. It was working when called in my controllers but no in Global.asax. Here is the error.


Compiler Error Message: CS7036: There is no argument given that corresponds to the required formal parameter 'genreService' of 'MvcApplication.MvcApplication(IGenreService)'


Global.asax.cs

public class MvcApplication : System.Web.HttpApplication
{
private readonly IGenreService _genreService;

public MvcApplication(IGenreService genreService)
{
_genreService = genreService;
}

protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}


GenreService.cs

public partial class GenreService : IGenreService
{
private readonly IRepository<Genre> _genreRepository;
private readonly IRepository<GameGenre> _gameGenreRepository;

public GenreService(IRepository<Genre> genreRepository, IRepository<GameGenre> gameGenreRepository)
{
_genreRepository = genreRepository;
_gameGenreRepository = gameGenreRepository;
}

// methods
}


IGenreService.cs

public partial interface IGenreService
{
// interface
}


UnityConfig.cs

using System;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using System.Data.Entity;
using Microsoft.AspNet.Identity;
using Microsoft.Owin.Security;
using GameCommerce.Infrastructure.Services.GameLibrary;
using GameCommerce.Infrastructure;
using Microsoft.AspNet.Identity.EntityFramework;
using GameCommerce.Infrastructure.ApplicationUsers;
using System.Web;
using GameCommerce.Infrastructure.Services.Message;

namespace GameCommerce.Web.App_Start
{
/// <summary>
/// Specifies the Unity configuration for the main container.
/// </summary>
public class UnityConfig
{
#region Unity Container
private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
{
var container = new UnityContainer();
RegisterTypes(container);
return container;
});

/// <summary>
/// Gets the configured Unity container.
/// </summary>
public static IUnityContainer GetConfiguredContainer()
{
return container.Value;
}
#endregion

/// <summary>Registers the type mappings with the Unity container.</summary>
/// <param name="container">The unity container to configure.</param>
/// <remarks>There is no need to register concrete types such as controllers or API controllers (unless you want to
/// change the defaults), as Unity allows resolving a concrete type even if it was not previously registered.</remarks>
public static void RegisterTypes(IUnityContainer container)
{
// NOTE: To load from web.config uncomment the line below. Make sure to add a Microsoft.Practices.Unity.Configuration to the using statements.
// container.LoadConfiguration();

// TODO: Register your types here
// container.RegisterType<IProductRepository, ProductRepository>();

container.RegisterType<DbContext, ApplicationDbContext>(new HierarchicalLifetimeManager());
container.RegisterType<UserManager<ApplicationUser>>(new HierarchicalLifetimeManager());
container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(new InjectionConstructor(new ApplicationDbContext()));
container.RegisterType<Areas.Admin.Controllers.AccountController>(new InjectionConstructor());
container.RegisterType<Controllers.AccountController>(new InjectionConstructor());
container.RegisterType<IAuthenticationManager>(new InjectionFactory(o => HttpContext.Current.GetOwinContext().Authentication));

container.RegisterType(typeof(IRepository<>), typeof(Repository<>));
container.RegisterType<IGameService, GameService>();
container.RegisterType<IGenreService, GenreService>();
container.RegisterType<IGameDeveloperService, GameDeveloperService>();
container.RegisterType<IGamePublisherService, GamePublisherService>();
container.RegisterType<IMessageService, MessageService>();
}
}
}

Answer

Try with the below code:

using Microsoft.Practices.Unity;
public class MvcApplication : System.Web.HttpApplication
    {
        private readonly IGenreService _genreService;

        public MvcApplication()
        {
            _genreService = GameCommerce.Web.App_Start.UnityConfig.GetConfiguredContainer().Resolve<IGenreService>();
        }

        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
        }
    }

DepedencyResolver in MVC by default is used for resolution in controllers, so here we are using explicity using the Container for resolution in 'MvcApplication'.