14

Global.asax.csに次のようなコンポーネントを登録しました。

ContainerBuilder builder = new ContainerBuilder();
builder.RegisterControllers(Assembly.GetExecutingAssembly());

builder.RegisterType<WebWorkContext>().As<IWorkContext>().InstancePerHttpRequest();

IContainer container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

// This is where my error happens, not sure why?
var workContext = container.Resolve<IWorkContext>();

WebWorkContextクラス:

public class WebWorkContext : IWorkContext
{
     // Left out other code
}

IWorkContextインターフェース:

public interface IWorkContext
{
     // Left out other code
}

私が得ているエラーは次のとおりです。

タグが「httpRequest」に一致するスコープは、インスタンスがリクエストされたスコープからは見えません。これは通常、HTTPごとのリクエストとして登録されたコンポーネントがSingleInstance()コンポーネント(または同様のシナリオ)によってリクエストされていることを示します。Web統合では、コンテナ自体からではなく、常にDependencyResolver.CurrentまたはILifetimeScopeProvider.RequestLifetimeから依存関係をリクエストします。 。

これを機能させるにはどうすればよいですか?私がこのようにしたい理由は、作業コンテキストが現在の顧客の取得などを処理するためです。

さらにいくつか質問があります。一度に登録するのが賢明/ベストプラクティスですか?別の段階でコンポーネントを追加する必要があるシナリオはありますか?

4

2 に答える 2

22

でマークされた登録は、InstancePerHttpRequest各HTTPリクエスト中に作成および破棄される特定のネストされたライフタイムスコープから解決されることが期待されます。

コンストラクターパラメーターとしてコントローラーの1つに追加するIWorkContextと、インスタンスが挿入されていることがわかります。コードでは、ネストされた「リクエストごと」のライフタイムスコープではなく、ルートライフタイムスコープからサービスを解決しようとしています。

アプリケーションを実行せずにサービスの解決をテストする場合は、HTTPリクエスト中に作成されたものと同じタグを使用してライフタイムスコープを作成する必要があります。MVC 3統合では、ライフタイムスコープは「httpRequest」とタグ付けされています。

using (var httpRequestScope = container.BeginLifetimeScope("httpRequest"))
{
    Assert.That(httpRequestScope.Resolve<IWorkContext>(), Is.Not.Null);
}

文字列値をハードコーディングする必要がないように、MVC統合を更新して「httpRequest」タグ名をAPIを介して公開するようにします。ASP.NETランタイムの外部でライフタイムスコープの作成を制御できるように、独自のILifetimeScopeProvider実装をに渡すこともできます。AutofacDependencyResolverこれは、使用可能なHTTPリクエストがない場合の単体テストで役立ちます。

于 2012-04-06T04:12:40.580 に答える
2

私はWebFormsでこれを行っています:

this.RoutingService = ((Global)HttpContext.Current.ApplicationInstance).ContainerProvider.RequestLifetime.Resolve<RoutingService>();
于 2012-07-23T01:43:51.107 に答える