19

トレースは次のとおりです。

<Error>
   <Message>An error has occurred.</Message>

   <ExceptionMessage>
      Type 'ProjectName.Web.Api.Controllers.ContinentsController' does not have a default constructor
   </ExceptionMessage>

   <ExceptionType>System.ArgumentException</ExceptionType>

   <StackTrace>
      at System.Linq.Expressions.Expression.New(Type type)

      at System.Web.Http.Internal.TypeActivator.Create[TBase](Type instanceType)

      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>
</Error>

うまく機能しているので、これは奇妙だと思いますpublic class UsersController : ApiController { ... }。2 つのコントローラーを比較しましたが、すべての設定と構造は似ています。

私はAsp.Net Mvc 4 と Web Api: Building a REST Service from Start to Finish にNinject似たシステム設定を使用しています。Jamie Kurtz

スタック トレースから、問題とその解決方法を特定できる人はいますか? ありがとう!

要求どおり。

大陸コントローラー

[LoggingNHibernateSession]
public class ContinentsController : ApiController
{
    private readonly ISession _session;
    private readonly IContinentMapper _continentMapper;
    private readonly IHttpContinentFetcher _httpContinentFetcher;
    private readonly IDateTime _dateTime;

    public ContinentsController(ISession session, IContinentMapper continentMapper, IHttpContinentFetcher continentFetcher, IDateTime dateTime)
    {
        _session = session;
        _continentMapper = continentMapper;
        _httpContinentFetcher = continentFetcher;
        _dateTime = dateTime;
    }

    public IEnumerable<Continent> Get()
    {
        var continents = _session
            .Query<Data.Model.Continent>()
            .Select(_continentMapper.CreateContinent)
            .ToList();

        return continents;
    }

    public Continent Get(long id)
    {
        var modelContinent = _httpContinentFetcher.GetContinent(id);
        var continent = _continentMapper.CreateContinent(modelContinent);

            return continent;
        }
  }

UsersController : 正常に動作します。

    public class UsersController : ApiController
    {
        private readonly ISession _session;
        private readonly IUserManager _userManager;
        private readonly IUserMapper _userMapper;
        private readonly IHttpUserFetcher _userFetcher;

        public UsersController(
            IUserManager userManager,
            IUserMapper userMapper,
            IHttpUserFetcher userFetcher,
            ISession session)
        {
            _userManager = userManager;
            _userMapper = userMapper;
            _userFetcher = userFetcher;
            _session = session;
        }

        [Queryable]
        public IQueryable<Data.Model.User> Get()
        {
            return _session.Query<Data.Model.User>();
        }

        [LoggingNHibernateSession]
        public User Get(Guid id)
        {
            var user = _userFetcher.GetUser(id);
            return _userMapper.CreateUser(user);
        }
    }

私は使用してNinjectWebCommon.csおり、その中には、これと他のいくつかのデフォルトの方法があります。

        private static void RegisterServices(IKernel kernel)
        {
            var containerConfigurator = new NinjectConfigurator();
            containerConfigurator.Configure(kernel);

            GlobalConfiguration.Configuration.MessageHandlers.Add(kernel.Get<BasicAuthenticationMessageHandler>());
        }

それから私は持っていますNinjectConfigurator.cs

public class NinjectConfigurator
{
    ......
    private void AddBindings(IKernel container)
        {
            .....
            container.Bind<IDateTime>().To<DateTimeAdapter>();
            container.Bind<IDatabaseValueParser>().To<DatabaseValueParser>();

            //HttpFetchers
            container.Bind<IHttpUserFetcher>().To<HttpUserFetcher>();
            container.Bind<IHttpContinentFetcher>().To<HttpContinentFetcher>();                                

            //TypeMappers
            container.Bind<IUserManager>().To<UserManager>();
            container.Bind<IMembershipInfoProvider>().To<MembershipAdapter>();
            container.Bind<IUserMapper>().To<UserMapper>();
            container.Bind<IContinentMapper>().To<ContinentMapper>();    
            .........
        }
     .......
}

NinjectWebCommon.csとの両方NinjectConfigurator.csApp_Startフォルダにあります。

container.Bind<ISession>().ToMethod(CreateSession);ですNHibernateNinjectConfigurator.cs中にありますprivate void ConfigureNHibernate(IKernel container) { ... }

4

10 に答える 10

18

Web API の依存関係を正しく解決する方法を Ninject に伝える必要があります。

Felipe Oriani の回答を使用できますが、必要に応じて、これを行う WebApiContrib.IoC.Ninject という NuGet パッケージがあります。

  1. Visual Studio の場合: [ツール] > [NuGet パッケージ マネージャー] > [ソリューションの NuGet パッケージの管理] に移動します。

  2. WebApiContrib.IoC.Ninjectパッケージをインストールする

  3. 編集: NinjectWebCommon.csを作成し、 CreateKernel()メソッドを更新して以下を含めます: GlobalConfiguration.Configuration.DependencyResolver = new NinjectResolver(kernel);

    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;
        }
    }
    
于 2015-01-07T21:25:05.793 に答える
2

私もこの同じエラーに遭遇しましたが、Ninject. 私は実際に依存関係リゾルバーと構成を正しくしました。実際、別の新しい依存関係を解決しようとするまで、アプリはうまく機能していました。登録を設定していたので、何が欠けているのかわかりませんでした。

問題は、適切な具象型に解決するのではなく、誤ってインターフェイスを同じインターフェイスに解決したことです。したがって、OPの例を使用して、次のことを行った結果、同じエラーが発生しました。

container.Bind<IUserManager>().To<IUserManager>();

どちらを解決するIUserManagerかは見落としでしたが OPから同じエラーが発生することに注意してください。明らかに、修正は適切な具体的なタイプに解決することです。

于 2014-09-16T22:07:56.720 に答える