私はこれに従ってきましたチュートリアルこれは、追加のコンストラクターを持つように変更するまではうまく機能していましDbContext
た。現在、解像度に問題があり、これを修正するにはどうすればよいかわかりません。パラメーターなしのコンストラクターを強制的に取得する簡単な方法はありますか、それとも私が間違ったアプローチをしているのでしょうか?
DbContext
2 つのコンストラクタがあります:
public class DashboardDbContext : DbContext
{
public DashboardDbContext() : base("DefaultConnection") { }
public DashboardDbContext(DbConnection dbConnection, bool owns)
: base(dbConnection, owns) { }
}
SiteController
コンストラクタ:
private readonly IDashboardRepository _repo;
public SiteController(IDashboardRepository repo)
{
_repo = repo;
}
リポジトリ:
DashboardDbContext _context;
public DashboardRepository(DashboardDbContext context)
{
_context = context;
}
UnityResolver
コード:
public class UnityResolver : IDependencyResolver
{
private readonly IUnityContainer _container;
public UnityResolver(IUnityContainer container)
{
_container = container;
}
public object GetService(Type serviceType)
{
try
{
return _container.Resolve(serviceType);
}
catch (ResolutionFailedException)
{
return null;
}
}
public IEnumerable<object> GetServices(Type serviceType)
{
try
{
return _container.ResolveAll(serviceType);
}
catch (ResolutionFailedException)
{
return new List<object>();
}
}
public IDependencyScope BeginScope()
{
var child = _container.CreateChildContainer();
return new UnityResolver(child);
}
public void Dispose()
{
_container.Dispose();
}
}
WebAPI構成:
var container = new UnityContainer();
container.RegisterType<IDashboardRepository, DashboardRepository>(new HierarchicalLifetimeManager());
config.DependencyResolver = new UnityResolver(container);
WebApi 呼び出しからのエラー:
System.InvalidOperationException: 'SiteController' タイプのコントローラーを作成しようとしたときにエラーが発生しました。コントローラーにパラメーターなしのパブリック コンストラクターがあることを確認してください。
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()
InnerException: System.ArgumentException: 型 'Dashboard.Web.Controllers.SiteController' には既定のコンストラクターがありません。
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)
チュートリアルは素晴らしく、2 番目のコンストラクターを追加するまではうまく機能していました。
ベストアンサー1
何が起こっているかというと、あなたは噛まれているのですこの問題基本的に、コントローラーをコンテナーに明示的に登録しなかったことが原因です。Unity は未登録の具体的な型を解決しようとしますが、解決できないため (構成エラーが原因)、null を返します。Web API が契約により強制的に null を返すため、強制的に null を返します。Unity は null をIDependencyResolver
返すため、Web API はコントローラー自体を作成しようとしますが、既定のコンストラクターがないため、「コントローラーにパラメーターなしのパブリック コンストラクターがあることを確認してください」という例外がスローされます。この例外メッセージは誤解を招きやすく、実際の原因を説明していません。
コントローラーを明示的に登録すると、はるかに明確な例外メッセージが表示されるため、常にすべてのルート タイプを明示的に登録する必要があります。
しかし、もちろん、構成エラーは に 2 番目のコンストラクターを追加したことから発生しますDbContext
。Unity は常に引数が最も多いコンストラクターを選択しようとしますが、この特定のコンストラクターを解決する方法がわかりません。
本当の原因は、Unityの自動配線機能を使用して を作成しようとしていることですDbContext
。DbContext
は、自動配線されるべきではない特別な型です。 これはフレームワーク型であり、したがって、ファクトリーデリゲートを使用して登録する代わりに:
container.Register<DashboardDbContext>(
new InjectionFactory(c => new DashboardDbContext()));