トレースは次のとおりです。
_<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つのコントローラーを比較しましたが、すべての設定と構造は似ています。
私はNinject
を使用しており、_Jamie Kurtz
_に似たシステム設定を持っています Asp.Net Mvc 4およびWeb API:REST=開始から終了まで 。
スタックトレースから、だれでも問題を見つけて解決する方法はありますか?ありがとう!
リクエストに応じて
ContinentsController
_[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.cs
_の両方が_App_Start
_フォルダーにあります。
container.Bind<ISession>().ToMethod(CreateSession);
はNHibernate
です。 private void ConfigureNHibernate(IKernel container) { ... }
内の_NinjectConfigurator.cs
_内にあります
このエラーは、アプリケーションで依存関係リゾルバーを設定しない場合の既知のエラーです。 Controller Factoryは、コントローラーを作成してアクションメソッド(または動詞メソッド?)を実行するパラメーターなしのコンストラクターを見つけることができませんでした。そのため、依存関係リゾルバークラスを作成し、Webアプリの初期化時に設定する必要があります。コントローラーの依存関係を解決します。
ninject
を使用すると、次のようなものを試すことができます。
using Ninject;
using Ninject.Syntax;
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Web.Http.Dependencies;
namespace MyApplication.App_Start
{
public class NinjectDependencyScope : IDependencyScope
{
private IResolutionRoot resolver;
internal NinjectDependencyScope(IResolutionRoot resolver)
{
Contract.Assert(resolver != null);
this.resolver = resolver;
}
public void Dispose()
{
IDisposable disposable = resolver as IDisposable;
if (disposable != null)
disposable.Dispose();
resolver = null;
}
public object GetService(Type serviceType)
{
if (resolver == null)
throw new ObjectDisposedException("this", "This scope has already been disposed");
return resolver.TryGet(serviceType);
}
public IEnumerable GetServices(Type serviceType)
{
if (resolver == null)
throw new ObjectDisposedException("this", "This scope has already been disposed");
return resolver.GetAll(serviceType);
}
}
public class NinjectDependencyResolver : NinjectDependencyScope, IDependencyResolver
{
private IKernel kernel;
public NinjectDependencyResolver(IKernel kernel)
: base(kernel)
{
this.kernel = kernel;
}
public IDependencyScope BeginScope()
{
return new NinjectDependencyScope(kernel.BeginBlock());
}
}
}
NinjectDependencyResolver
クラスはNinject StandardKernel
オブジェクトをコンストラクター引数として使用し、依存関係スコープがパイプライン化されるたびにこの参照が使用されます。これをすべて機能させるために、NinjectDependencyResolver
クラスがアプリケーションのグローバル構成に割り当てられます。
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
// register all your dependencies on the kernel container
RegisterServices(kernel);
// register the dependency resolver passing the kernel container
GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);
return kernel;
}
Global.asax.cs
ファイルをApplication_Startイベントの最後に、このCreateKernel
メソッドを呼び出します。
Web APIの依存関係を正しく解決する方法をNinjectに伝える必要があります。
Felipe Orianiの答えを使用できますが、必要に応じてこれを行うWebApiContrib.IoC.NinjectというNuGetパッケージがあります。
Visual Studioの場合:[ツール]> [NuGetパッケージマネージャー]> [ソリューション用のNuGetパッケージの管理]
WebApiContrib.IoC.Ninjectパッケージをインストールします
編集: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;
}
}
私にとっては、Ninject.Web.WebApi.Webhost NuGetパッケージを追加するだけでした。
MVCとWebApi2の両方を使用するアプリケーションの場合、Ninjectには次のパッケージがあります。
私もこの同じエラーに遭遇しましたが、Ninject
を使用した別の原因からです。実際には、依存関係リゾルバーと構成が正しいものでした。実際、別の新しい依存関係を解決しようとするまで、アプリはうまく機能していました。登録が設定されているので、何が欠けているのかわかりませんでした。
問題は、私が偶然インターフェースを同じインターフェースに解決したのに対し、適切な具体的なタイプに解決することでした。そのため、OPの例を使用して次のことを行いましたが、同じエラーになります。
container.Bind<IUserManager>().To<IUserManager>();
IUserManager
の解決に注意してください。これは見落としでしたが、does OPからの同じエラーにつながります。明らかに、修正は適切な具体的な型に解決することです。
多くの人々がこの問題を抱えていたため、2016年にはそのためのレシピがあります。これは受け入れられた答えに追加されます。
私が行う方法は、パッケージNinject.MVC3
およびWebApiContrib.IoC.Ninject
をインストールすることです。 NinjectWebCommon
というファイルがApp_Start
フォルダーに追加されます。その後、組み込みのNinjectResolver
を使用できます。
このメソッドを追加するだけです:
private static void AddWebApiSupport(StandardKernel kernel)
{
// Support WebAPI
GlobalConfiguration.Configuration.DependencyResolver = new NinjectResolver(kernel);
GlobalConfiguration.Configuration.Services.Add(typeof(IFilterProvider), new NinjectWebApiFilterProvider(kernel));
}
RegisterServices
を呼び出す前に呼び出します。
Web.configファイルで依存関係注入のインターフェイスとクラスに言及していなかったときに、それが起こっていました。
SimpleInjector
ユーザーがここにいる場合...
私にとっては、単にSimpleInjectorInitializer.Initialize();
をApplication_Start()
メソッドに追加するのを忘れていただけです。
私は通常、SimpleInjectorInitializer
クラスを最近_App_Start
_フォルダーに作成し、その中でcontainer.Verify()
およびGlobalConfiguration.Configuration.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);
呼び出しを行います。すべての型登録などを行うGetInitializeContainer()
メソッドを呼び出した後.
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<ICountingKsRepository>().To<CountingKsRepository>();
To <>部分がインターフェイスではなく具象クラスであることを確認してください。同じエラーが発生するためです!
私もこの問題を抱えていましたが、インターフェイスの1つが実際にはどのクラスにも実装されていないことがわかりました(クラス宣言に追加するのを忘れていました)。
これは、主にNinject Dependency Injection Containerで作業するときに発生する一般的な問題です。この問題を解決するには、手順に従ってください。
App_startフォルダーを確認します。次のもの(NinjectWebcommon.cs)が見つかります。
ダブルクリックして、次のようなCreateKernel()メソッドの次の行をチェックします
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);
GlobalConfiguration.Configuration.DependencyResolver = new NinjectResolver(kernel);
return kernel;
}
catch
{
kernel.Dispose();
throw;
}
}
そして、このようにあなたの依存関係を登録します
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IProductDetails>().To<ProductDetails>().InRequestScope();
}
これにより、ソリューションが機能するはずです。