0

I'm using mvc web api. I have a generic IRepository and IUnitOfWork library which works perfect in asp.net mvc but when I intended to use it in my mvc web api project my repository object becomes null and consequently leads to exception. my repository and UnitOfWork objects are being instantiated and initialized inside a constructor which takes one IunitOfWork object as a parameter

here is the code (constructor code)

private IRepository<AspNetUserAccount> AccountRepository;
    private IRepository<Doctor> DoctorRepository;
    private readonly IUnitOfWork UnitOfWork;
    public AccountController(IUnitOfWork unitOfWork)
    {
        UnitOfWork = unitOfWork;
        AccountRepository = unitOfWork.Repository<AspNetUserAccount>();
        DoctorRepository = unitOfWork.Repository<Doctor>();
    }
    public AccountController()
    {

    }

and here is the usage of my Repository and UnitOfWork objects in Register action of Account controller.

 [AllowAnonymous]
 [Route("Register")]
 public ResultViewModel Register([FromBody]UserBindingModel model)
    {
        if (!ModelState.IsValid)
        {
            return new ResultViewModel(400, "Model Is Not Valid");
        }
        using (DigiTebDBContext db = new DigiTebDBContext())
        {
            using (var Transaction = db.Database.BeginTransaction())
            {
                try
                {
                    var user = new ApplicationUser()
                    {
                        UserName = model.UserName,
                        Email = model.Email
                        ,
                        CreateTimeStamp = DateTime.Now,
                        LastModifiedTimeStamp = DateTime.Now
                    };
                    IdentityResult result = UserManager.Create(user, model.Password);

                    if (!result.Succeeded)
                        throw new Exception(((string[])result.Errors)[0]);
                    UserUtility.AssignRoleToUser(user.Id, "Operator");
                    var Account = new AspNetUserAccount
                    {
                        AccountTypeValue = AccountType.Demo,
                        CreateTimeStamp = DateTime.Now
                    ,
                        CreateUserId = user.Id,
                        CurrentUserCount = 0,
                        MaxUserCount = 1,
                        IsMultiUser = false
                    ,
                        ExpiryDate = DateTime.Now,
                        LastModifiedUserId = user.Id,
                        LastModifiedTimeStamp = DateTime.Now
                    };
                    AccountRepository.Insert(Account);
                    UnitOfWork.Save();

                    Transaction.Commit();
                    return new ResultViewModel(200, "Registeration was successfull");
                }
                catch(Exception ex)
                {
                    Transaction.Rollback();
                    return new ResultViewModel(400, ex.Message);
                }
                finally
                {
                    UnitOfWork.Dispose();
                }

            }
        }

My problem is that my Repository (AccountRepository) and UnitOfWork (UnitOfWork) objects are being instantiated and initialized in a constructor that will never be called. when an action is called (no matter what) only parameterless constructor is being called and not my desired constructor with one parameter.

How can I change it so that the desired constructor being called instead of default parameterless constructor, in other word how can I determine which constructor is being called when an action is called in mvc web api???

I searched a bit about it and I figured that I can use the DI to resolve this issue, I used Ninject but I don't know how and where exactly I should write my codes (using Ninject) to change the default constructor of my Account class (Controller) and set it to another constructor

here is my Ninject modifications in NinjectWebCommon.cs in App_Start folder

 private static IKernel CreateKernel()
    {
        var kernel = new StandardKernel();
        try
        {
            kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
            kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

            RegisterServices(kernel);
            return kernel;
        }
        catch
        {
            kernel.Dispose();
            throw;
        }
    }
    private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind(typeof(IRepository<AspNetUserAccount>)).To(typeof(Repository<AspNetUserAccount>)).InRequestScope();
        kernel.Bind(typeof(IDataContext)).To(typeof(DigiTebDBContext)).InRequestScope();

        kernel.Bind(typeof(IUnitOfWork)).To(typeof(UnitOfWork)).InRequestScope();

        kernel.Bind<HttpContext>().ToMethod(ctx => HttpContext.Current).InTransientScope();
    }        

Thanks in advance

Code_Worm
  • 4,069
  • 2
  • 30
  • 35
  • the default controller factory of the framework uses the parameter-less constructor. lookup `DependencyResolver` – Nkosi Aug 02 '16 at 19:52

1 Answers1

0

I found the answer the myself originally from this link MVC 4 Web Api Controller does not have a default constructor?

first the WebApiContrib.IoC.Ninject should be installed frm Nuget and then CreateKernel in NinjectWebCommon.cs function should be modified like below

private static IKernel CreateKernel()
{
var kernel = new StandardKernel();

try
{
    kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
    kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

    RegisterServices(kernel);

    //Note: Add the line below:
    GlobalConfiguration.Configuration.DependencyResolver = new NinjectResolver(kernel);

    return kernel;
}
catch
{
    kernel.Dispose();
    throw;
}
}

by doing so when I comment the default parameterless constructor in my controller, the DI (in this case ninject) recognize the alternative constructor (in this case the constructor with one parameter) itself

Community
  • 1
  • 1
Code_Worm
  • 4,069
  • 2
  • 30
  • 35