They gave the task to load the controller constructor into the class Repository, which implements the Repository interface. Found an example
[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(API.App_Start.NinjectWebCommon), "Start")] [assembly: WebActivatorEx.ApplicationShutdownMethodAttribute(typeof(API.App_Start.NinjectWebCommon), "Stop")] namespace API.App_Start { using System; using System.Web; using Microsoft.Web.Infrastructure.DynamicModuleHelper; using Ninject; using Ninject.Web.Common; using DataAccess; public static class NinjectWebCommon { private static readonly Bootstrapper bootstrapper = new Bootstrapper(); /// <summary> /// Starts the application /// </summary> public static void Start() { DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule)); DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule)); bootstrapper.Initialize(CreateKernel); } /// <summary> /// Stops the application. /// </summary> public static void Stop() { bootstrapper.ShutDown(); } /// <summary> /// Creates the kernel that will manage your application. /// </summary> /// <returns>The created kernel.</returns> private static IKernel CreateKernel() { var kernel = new StandardKernel(); try { kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel); kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>(); System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver = new Ninject.WebApi.DependencyResolver.NinjectDependencyResolver(kernel);//Добавил строчку вот тут RegisterServices(kernel); return kernel; } catch { kernel.Dispose(); throw; } } /// <summary> /// Load your modules or register your services here! /// </summary> /// <param name="kernel">The kernel.</param> private static void RegisterServices(IKernel kernel) { kernel.Bind<Repository>().ToConstructor(i => new Repository(i.Inject<QueueDB>())); kernel.Bind<IRepository>().To<Repository>(); } } } Here it is the controller itself. In the constructor, passing the IRepository interface
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Web.Http; using DataAccess; namespace API.Controllers { [Authorize] public class ValuesController : ApiController { IRepository _repository; public ValuesController(IRepository repository) { _repository = repository; } // GET api/values public IEnumerable<string> Get() { return new string[] { "value1" }; } // GET api/values/5 public string Get(int id) { return "value"; } // POST api/values public void Post([FromBody]string value) { } // PUT api/values/5 public void Put(int id, [FromBody]string value) { } // DELETE api/values/5 public void Delete(int id) { } } } At the same time, the implementation of the interface, the Repository class, takes as its constructor argument the IContext interface (which we are also behind) from which the QueueDB class implements.
using System; using System.Collections.Generic; using System.Linq; using System.Data.Entity; using System.Threading.Tasks; using Entity; namespace DataAccess { public class Repository : IRepository { private IContext _context; public Repository(IContext context) { if (context == null) throw new NullReferenceException("Context is null"); this._context = context; } public void AddQueue(Queue queue) { _context.Queues.Add(queue); _context.SaveChanges(); } public void AddUser(User user) { _context.Users.Add(user); _context.SaveChanges(); } public void AddUserInQueue(User user, Queue queue) { UserState state = new UserState { Queue = queue, User = user }; _context.States.Add(state); _context.SaveChanges(); } public void DeleteQueue(Queue queue) { _context.Delete(queue); _context.SaveChanges(); } public void DeleteUser(User user) { _context.Delete(user); _context.SaveChanges(); } public void DeleteUserFromQueue(User user, Queue queue) { UserState state = user.States.FirstOrDefault(s => s.Queue.Id.Equals(queue.Id));//Яне буду использовать include, буду надется на lazy loading if (state == null) throw new NullReferenceException(string.Format("User (systemName: {0}) not a member Queue (id: {1})", user.SystemName, queue.Id)); else { _context.Delete(state); _context.SaveChanges(); } } public void Dispose() { _context.Dispose(); } public void EditQueue(Queue edit) { _context.Update(edit); } public void EditUser(User edit) { _context.Update(edit); _context.SaveChanges(); } public ICollection<Queue> GetAllQueue() { return _context.Queues.ToList(); } public ICollection<User> GetAllUser() { return _context.Users.ToList(); } public Queue GetQueueById(Guid id) { Queue queue = _context.Queues.FirstOrDefault(q => q.Id.Equals(id)); if (queue == null) throw new NullReferenceException(string.Format("Queue (id: {0}) not fount", id)); else return queue; } public User GetUserBySystemName(string systemName) { User user = _context.Users.FirstOrDefault(u => u.SystemName.Equals(systemName)); if (user == null) throw new NullReferenceException(string.Format("User (systemName: {0}) not fount", systemName)); else return user; } public bool HasUser(string systemName) { return _context.Users.FirstOrDefault(u => u.SystemName.Equals(systemName)) != null; } } } But when accessing the controller ValuesController error appears:
<Error> <Message>Произошла ошибка.</Message> <ExceptionMessage> Произошла ошибка при попытке создать контроллер типа "ValuesController". Убедитесь в том, что контроллер имеет общедоступный конструктор без параметров. </ExceptionMessage> <ExceptionType>System.InvalidOperationException</ExceptionType> <StackTrace> в System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType) в System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request) в System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext() </StackTrace> <InnerException> <Message>Произошла ошибка.</Message> <ExceptionMessage> Тип "API.Controllers.ValuesController" не содержит конструктор по умолчанию </ExceptionMessage> <ExceptionType>System.ArgumentException</ExceptionType> <StackTrace> в System.Linq.Expressions.Expression.New(Type type) в System.Web.Http.Internal.TypeActivator.Create[TBase](Type instanceType) в System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator) в System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType) </StackTrace> </InnerException> </Error> I took an example from here
kernel.Bind<IContext>().To<QueueDB>();instead ofkernel.Bind<Repository>().ToConstructor(...)- kmv