2

ここで説明するように、コントローラーアクションインジェクションを利用しようとしているASP.NETMVC3アプリケーションを作成しています。

コントローラコンストラクタインジェクションは問題なく機能しますが、アクションインジェクションを機能させることができないようです。

Global.asaxでAutofacを次のように設定しました。

var builder = new ContainerBuilder();

builder.Register<ITestInject>(c => new TestInject { TestString = "hi" });

builder.RegisterType<ExtensibleActionInvoker>().As<IActionInvoker>();
builder.RegisterControllers(typeof(MvcApplication).Assembly).InjectActionInvoker();

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

そして、私のコントローラーには次のようなアクションがあります。

public ActionResult Test(ITestInject testInject)
{
        return View(testInject);
}

TestInject/ITestInjectクラス/インターフェイスは次のように定義されます。

public interface ITestInject
{
    string TestString { get; }
}
public class TestInject : ITestInject
{
    public string TestString { get; set; }
}

テストアクションに移動しようとすると、次のエラーが表示されます。

'/'アプリケーションのサーバーエラー。

インターフェイスのインスタンスを作成できません。

説明:現在のWebリクエストの実行中に未処理の例外が発生しました。エラーとエラーがコードのどこで発生したかについての詳細は、スタックトレースを確認してください。

例外の詳細:System.MissingMethodException:インターフェイスのインスタンスを作成できません。

ソースエラー:

現在のWebリクエストの実行中に、未処理の例外が生成されました。例外の発生源と場所に関する情報は、以下の例外スタックトレースを使用して識別できます。

スタックトレース:

[MissingMethodException:インターフェイスのインスタンスを作成できません。]
   System.RuntimeTypeHandle.CreateInstance(RuntimeType type、Boolean publicOnly、Boolean noCheck、Boolean&canBeCached、RuntimeMethodHandleInternal&ctor、Boolean&bNeedSecurityCheck)+0
   System.RuntimeType.CreateInstanceSlow(ブール値publicOnly、ブール値skipCheckThis、ブール値fillCache)+98
   System.RuntimeType.CreateInstanceDefaultCtor(ブールpublicOnly、ブールskipVisibilityChecks、ブールskipCheckThis、ブールfillCache)+241
   System.Activator.CreateInstance(Type type、Boolean nonPublic)+69
   System.Web.Mvc.DefaultModelBinder.CreateModel(ControllerContext controllerContext、ModelBindingContext bindingContext、Type modelType)+199
   System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext、ModelBindingContext bindingContext)+572
   System.Web.Mvc.DefaultModelBinder.BindModel(ControllerContext controllerContext、ModelBindingContext bindingContext)+449
   System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext、ParameterDescriptor parameterDescriptor)+317
   Autofac.Integration.Mvc.ExtensibleActionInvoker.GetParameterValue(ControllerContext controllerContext、ParameterDescriptor parameterDescriptor)+122
   System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext、ActionDescriptor actionDescriptor)+117
   System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext、String actionName)+343
   System.Web.Mvc.Controller.ExecuteCore()+116
   System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext)+97
   System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext)+10
   System.Web.Mvc。<> c_DisplayClassb。<BeginProcessRequest> b _5()+37
   System.Web.Mvc.Async。<> c_DisplayClass1。<MakeVoidDelegate> b _0()+21
   System.Web.Mvc.Async。<> c_DisplayClass8`1。<BeginSynchronous> b _7(IAsyncResult )+12
   System.Web.Mvc.Async.WrappedAsyncResult`1.End()+62
   System.Web.Mvc。<> c_DisplayClasse。<EndProcessRequest> b_ d()+50
   System.Web.Mvc.SecurityUtil。<GetCallInAppTrustThunk> b _0(アクションf)+7
   System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(アクションアクション)+22
   System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult)+60
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result)+9
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()+8841105
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step、Boolean&completedSynchronously)+184

バージョン情報:Microsoft .NET Frameworkバージョン:4.0.30319; ASP.NETバージョン:4.0.30319.1

私がここで間違っていることについて何か考えはありますか?

Autofacバージョン2.4.5.724を使用しています。

ありがとう。

4

2 に答える 2

7

現在のAutofacMVC3実装では、アクションインジェクションはデフォルトでオフになっています。

これを有効にするには、以下にパラメーターを渡しますExtensibleActionInvoker

builder.RegisterType<ExtensibleActionInvoker>()
    .As<IActionInvoker>()
    .WithParameter("injectActionMethodParameters", true);

これはごく最近の変更であり、一部のドキュメントは更新する必要があります-面倒でごめんなさい。

于 2011-03-25T04:12:41.337 に答える
0

問題はこの行です

builder.Register<ITestInject>(c => new TestInject { TestString = "hi" });

Registerメソッドの最初のパラメーターは、登録する具体的なサービスです。そのタイプに続いて、「インスタンス化する方法」が続き、次に、サービスを公開する実際のインターフェースを定義するパラメーターが続きます。Autofacが実装をインスタンス化しようとするため、例外が発生します。これは、上記の場合はインターフェースです。明らかに、インターフェース型にはコンストラクターが見つかりません。

今これを見てください:

builder.Register<TestInject>(c => new TestInject { TestString = "hi" }).As<ITestInject>();

このアプローチIMOは、他のDIフレームワークと比較したAutofacsの強みの1つです。他の人が公開したいインターフェースで登録を開始し、実装で終わる場合、Autofacは実際の実装で始まり、インターフェースで終わります。これにより、特に1つの具体的な実装を複数のインターフェイスとして公開できる場合に、すべてを1つの登録でよりクリーンな構文にすることができます。

于 2011-03-24T22:10:41.813 に答える