Unityを使用してコントローラーの依存関係を解決するMVCWebApi owin(ソフトホスト)プロジェクトがあります
このように見えます
public class PacientaiController : ODataController
{
private readonly IEntityRepo<Ent.Pacientas> repo;
public PacientaiController(IEntityRepo<Ent.Pacientas> repo)
{
this.repo = repo;
}
私が解決しようとしている問題は、「OwinContex」をレポに渡す方法です。
public class PacientasEntityRepo:IEntityRepo<Pacientas>,IDisposable
{
public PacientasEntityRepo(IOwinContext ctx)
{
.........
このようにStartup.cs
に登録しようとすると
Container.RegisterType<IOwinContext>(new InjectionFactory(o => HttpContext.Current.GetOwinContext()));
HttpContext.Current
がNULLであるというnull参照を取得します
ここでの主なアイデアは、現在認証されているユーザーをリポジトリに渡すことです。これは、ユーザーに応じて、リポジトリがデータベースをクエリするためのロジックをホストするためです。 (たとえば、ユーザーが管理者の場合はこのデータを返し、ユーザーがゲストの場合はこのデータを返します)
重要なのは、これが自己ホストであるということです。
この設計を採用している理由を脇に置いて、問題に集中しましょう。IOwinContext
を挿入します。
HttpRequestMessage
メソッドを使用してGetOwinContext
インスタンスから取得することもできますが、何らかの方法でHttpRequestMessage
を取得する必要もあります。
Unityは、箱から出してHttpRequestMessage
を注入することをサポートしていませんが、ここで説明するように、現在のDelegatingHandler
をコンテナーに格納するカスタムHttpRequestMessage
を使用できます: Autofac を使用してWebAPIUrlHelperをサービスに挿入します
リンクされた質問はAutofacに関するものですが、Unityで作業するために転送できます。
CurrentRequest
とCurrentRequestHandler
は、 Andrew Davey の回答からそのまま使用できます。
public class CurrentRequest
{
public HttpRequestMessage Value { get; set; }
}
public class CurrentRequestHandler : DelegatingHandler
{
protected async override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
var scope = request.GetDependencyScope();
var currentRequest = (CurrentRequest)scope.GetService(typeof(CurrentRequest));
currentRequest.Value = request;
return await base.SendAsync(request, cancellationToken);
}
}
次に、DelegatingHandler
を次のものに登録する必要があります。
httpConfiguration.MessageHandlers.Insert(0, new CurrentRequestHandler());
そして、CurrentRequest
とIOwinContext
をコンテナに登録します
container.RegisterType<CurrentRequest>(
new HierarchicalLifetimeManager());
container.RegisterType<IOwinContext>(
new HierarchicalLifetimeManager(),
new InjectionFactory(c => c.Resolve<CurrentRequest>().Value.GetOwinContext()));
httpConfiguration.DependencyResolver = new UnityHierarchicalDependencyResolver(container);
カスタム委任ハンドラーのほかに、Web.APIにフックしてHttpRequestMessage
をキャプチャする場所が他にもあります。たとえば、独自のIHttpControllerActivator
を作成し、ここで説明するようにExecuteAsync
メソッドを使用できます。 : ASP.NET Web API 2での依存性注入
セルフホストアプリケーションでは、HttpContextがありません。状態を移動するには、別の方法が必要です。オプションは、次のような自己実装のHttpContextを使用することです。
https://github.com/danielcrenna/graveyard/tree/master/httpcontext-shim
問題は、Startupが呼び出されたときにHttpContextが存在しないことだと思います。したがって、おそらく必要なのは、代わりに次のようなFuncを使用することです。
public class PacientasEntityRepo:IEntityRepo<Pacientas>,IDisposable
{
public PacientasEntityRepo(Func<IOwinContext> ctx)
{
.........
次に、スタートアップのコードを次のように変更します。
Container.RegisterType<IOwinContext>(new InjectionFactory(() => HttpContext.Current.GetOwinContext()));