Определите, какой конструктор будет вызываться (изменить конструктор по умолчанию) при вызове действия в MVC Web API
Я использую веб-API MVC. У меня есть универсальная библиотека IRepository и IUnitOfWork, которая прекрасно работает в asp.net mvc, но когда я намеревался использовать ее в своем проекте mvc web api, мой объект хранилища становится нулевым и, следовательно, приводит к исключению. мой репозиторий и объекты UnitOfWork создаются и инициализируются внутри конструктора, который занимает один IunitOfWork
объект как параметр
вот код (код конструктора)
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()
{
}
а вот использование моих объектов Repository и UnitOfWork в Register
действие Account
контроллер.
[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();
}
}
}
Моя проблема в том, что мой репозиторий (AccountRepository)
и UnitOfWork (UnitOfWork)
объекты создаются и инициализируются в конструкторе, который никогда не будет вызываться. когда вызывается действие (не смотря ни на что), вызывается только конструктор без параметров, а не мой желаемый конструктор с одним параметром.
Как я могу изменить его так, чтобы требуемый конструктор вызывался вместо конструктора по умолчанию без параметров, другими словами, как я могу определить, какой конструктор вызывается при вызове действия в mvc web api???
Я искал немного об этом, и я решил, что я могу использовать DI для решения этой проблемы, я использовал Ninject, но я не знаю, как и где именно я должен написать свои коды (используя Ninject), чтобы изменить конструктор по умолчанию моего Account
класс (контроллер) и установить его в другой конструктор
вот мои Ninject модификации в NinjectWebCommon.cs
в App_Start
папка
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();
}
заранее спасибо
1 ответ
Я сам нашел ответ по этой ссылке MVC 4 Web Api Controller не имеет конструктора по умолчанию?
сначала нужно установить WebApiContrib.IoC.Ninject из Nuget, а затем CreateKernel
в NinjectWebCommon.cs
функция должна быть изменена, как показано ниже
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;
}
}
делая так, когда я комментирую конструктор по умолчанию без параметров в моем контроллере, DI (в данном случае ninject) распознает альтернативный конструктор (в данном случае конструктор с одним параметром)