Joe Ricklefs
Joe Ricklefs

Reputation: 660

Issues Using Dependency Injection with AccountController

I'm cleaning up and old app using MVC 5 EF,Identity, Unity I'm having trouble figuring out how to register the DI for the AccountController. in the In the Below example I changed the Empty Constructor from the following

      public AccountController()
    { }

To this

public AccountController(IDateTimeService dateTimeService, ILeagueLogic leagueLogic)
{
    _dateTimeService = dateTimeService;
    _leagueLogic = leagueLogic;
}

So in the full Controller I have the Following

  public class AccountController : Controller
{
    private ApplicationUserManager _userManager;
    private IDateTimeService _dateTimeService;
    private ILeagueLogic _leagueLogic;

         [InjectionConstructor] <-- Nailed it
    public AccountController(IDateTimeService dateTimeService, ILeagueLogic leagueLogic)
    {
        _dateTimeService = dateTimeService;
        _leagueLogic = leagueLogic;
    }

    public AccountController(ApplicationUserManager userManager, ApplicationSignInManager signInManager)
    {
        UserManager = userManager;
        SignInManager = signInManager;
    }

    public ApplicationUserManager UserManager
    {
        get
        {
            return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
        }
        private set
        {
            _userManager = value;
        }
    }

  private ApplicationSignInManager _signInManager;
    public ApplicationSignInManager SignInManager
    {
        get
        {
            return _signInManager ?? HttpContext.GetOwinContext().Get<ApplicationSignInManager>();
        }
        private set { _signInManager = value; }
    }


    //
    // GET: /Account/Login
    [AllowAnonymous]
    public ActionResult Login(string returnUrl)
    {
        ViewBag.ReturnUrl = returnUrl;
        return View();
    }

}

In the UnityConfig File I have the following

 public static void RegisterTypes(IUnityContainer container)
    {

        container.RegisterType<IDateTimeService, DateTimeService>();
        container.RegisterType<ILeagueLogic, LeagueLogic>();


        container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>();
        container.RegisterType<UserManager<ApplicationUser>>();
        container.RegisterType<DbContext, ApplicationDbContext>();
        container.RegisterType<ApplicationUserManager>();
       // container.RegisterType<AccountController>(new InjectionConstructor());  <-- Removed this line
    }

But I get

The type MyProgram.Controllers.AccountController does not have a constructor that takes the parameters ().

Kinda Stumped.,. I belive I need to Register the controller somehow not sure.. exactly how

Upvotes: 1

Views: 825

Answers (1)

Anton Sizikov
Anton Sizikov

Reputation: 9230

The last line

container.RegisterType<AccountController>(new InjectionConstructor());

explicitly tells Unity to create an AccountController instance using the new AccountController() constructor

Based on the docs the type registration should look like that:

    container.RegisterType<AccountController>(
               new InjectionConstructor(
                 container.Resolve< IDateTimeService>(), 
                 container.Resolve< IDateTimeService >()));

UPD: if you have just one constructor in your AccountController class, you may try to remove the container.RegisterType<AccountController>(new InjectionConstructor()); line completely. Unity should be able to construct an instance without a hint.

UPD2:

In case you have more than one constructor, but only one is used to construct an instance by Unity (for example the second one might be used in unit-test project) you could decorate the new ctor with [InjectionConstructor] attribute

[InjectionConstructor]
public AccountController(IDateTimeService dateTimeService, ILeagueLogic leagueLogic)
{
    _dateTimeService = dateTimeService;
    _leagueLogic = leagueLogic;
}

Upvotes: 4

Related Questions