2014-01-14 3 views
0

Используя ninject в течение нескольких лет (на базовом уровне), я изо всех сил пытаюсь заставить его работать с webapi2 в совершенно новом решении. Это отлично работало в моем приложении mvc4 с webapi.WebApi 2 и Ninject - не разрешает

ошибка:

Обычный подозреваемый, чтобы сказать вам, что связывание не работает

<Error> 
<Message>An error has occurred.</Message> 
<ExceptionMessage> 
An error occurred when trying to create a controller of type 'TenantController'. Make sure that the controller has a parameterless public constructor. 
</ExceptionMessage> 
<ExceptionType>System.InvalidOperationException</ExceptionType> 
<StackTrace> 
at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType) at System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request) at System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken) at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__0.MoveNext() 
</StackTrace> 
<InnerException> 
<Message>An error has occurred.</Message> 
<ExceptionMessage> 
Type 'AIControlPoint.Data.Api.Controllers.TenantController' does not have a default constructor 
</ExceptionMessage> 
<ExceptionType>System.ArgumentException</ExceptionType> 
<StackTrace> 
at System.Linq.Expressions.Expression.New(Type type) at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator) at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType) 
</StackTrace> 
</InnerException> 
</Error> 

Контроллер webapi2 достаточно прост и не будет работать, если я создаю контекст как часть инициализации

без параметров
public class TenantController : ApiController 
    { 
     private TenantConfigurationContext tenantContext; 

     public TenantController(TenantConfigurationContext tenantContext) 
     { 
      this.tenantContext = tenantContext; 

     } 

     public List<TenantConfiguration> Get() 
     { 
      var tenants = (from t in tenantContext.TenantConfigurations 
          select t) 
          .ToList(); 

      return tenants; 
     } 
    } 
} 

И мой NinjectWebCommon это

[assembly: WebActivator.PreApplicationStartMethod(typeof(AIControlPoint.Data.Api.App_Start.NinjectWebCommon), "Start")] 
[assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(AIControlPoint.Data.Api.App_Start.NinjectWebCommon), "Stop")] 

namespace AIControlPoint.Data.Api.App_Start 
{ 
    using System; 
    using System.Web; 

    using Microsoft.Web.Infrastructure.DynamicModuleHelper; 

    using Ninject; 
    using Ninject.Web.Common; 

    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(); 
      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; 
     } 

     /// <summary> 
     /// Load your modules or register your services here! 
     /// </summary> 
     /// <param name="kernel">The kernel.</param> 
     private static void RegisterServices(IKernel kernel) 
     { 
      kernel.Bind<TenantConfigurationContext>().To<TenantConfigurationContext>(); 
     }   
    } 
} 

В NuGet пакеты я смонтированные: Ninject, ninject.mvc3, ninject.web.common, ninject.webapi.dependencyresolver

Кто-нибудь удалось получить эту работу? Любая помощь приветствуется.

Благодаря Стивен

ответ

0

Вы создали экземпляр TenantConfigurationContext непосредственно внутри контроллера , который будет неидеальной TenantConfigurationContext. Если какая-либо реализация TenantConfigurationContext изменяется или выпущены новые версии этого компонента, вы должны сами изменить класс контроллера. Зависимость от впрыска устраняет герметичную муфту и делает приложение гибким, многоразовым. Вы используете Ninject как структуру зависимостей, но способ, которым вы пытаетесь ее реализовать, имеет некоторые проблемы . Ниже шаги:

Прежде всего, необходимо создать интерфейс и класс, как показано ниже:

public interface ITenantConfigurationContext 
{ 
    List<TenantConfiguration> TenantConfigurations(); 
} 
public class TenantConfigurationContext : ITenantConfigurationContext 
{ 
    public List<TenantConfiguration> TenantConfigurations() 
    { 
     return (get data from DB here); 
    } 
} 

Затем вызовете ITenantConfigurationContext в контроллер Web Api:

public class TenantController : ApiController 
{ 
    private ITenantConfigurationContext tenantContext; 
    public TenantController(ITenantConfigurationContext tenantContext) 
    { 
     this.tenantContext = tenantContext; 

    } 
    public List<TenantConfiguration> Get() 
    { 
     var tenants = (from t in tenantContext.TenantConfigurations 
         select t) 
         .ToList(); 

     return tenants; 
    } 
} 

Наконец, зарегистрировать ITenantConfigurationContext в Ninject :

private static void RegisterServices(IKernel kernel) 
{ 
    kernel.Bind<ITenantConfigurationContext>().To<TenantConfigurationContext>(); 
} 

Примечание:

Возможно, вам понадобится установить пакет Ninject.Web.WebApi-RC от NuGet.

+0

Извините, что я немного опоздал с ответом, но на месте! У меня был неправильный пакет самородок. –