生成されたコントローラーをMVCフレームワークに登録する方法は?
-
29-09-2019 - |
質問
モデルとコントローラークラスを生成するコードがいくつかあります。
public ActionResult Generate()
{
ModelGenerator model = new ModelGenerator("c:/Upload/SampleModel.cs", "CodeDOMSample");
model.addProperties();
model.addConstructor();
model.GenerateCSharpCode(model._outputFileName);
Type t = Generator.CompileDOM(model.targetUnit, "c:/Upload/ModelCode.dll", model.assemblies());
ControllerGenerator controller = new ControllerGenerator("c:/Upload/SampleController.cs", "CodeDOMSample",t);
controller.GenerateCSharpCode(controller._outputFileName);
Generator.CompileDOM(controller.targetUnit, "c:/Upload/ControllerCode.dll", controller.assemblies());
// Somehow register compiled Controller to MVC
return RedirectToAction("About");
}
生成されたコントローラーコードは次のようになります。
//------------------------------------------------------------------------------
// <auto-generated>
// Dieser Code wurde von einem Tool generiert.
// Laufzeitversion:4.0.30319.1
//
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
// der Code erneut generiert wird.
// </auto-generated>
//------------------------------------------------------------------------------
namespace CodeDOMSample
{
using System;
using System.Web;
using System.Web.MVC;
// Copyright (c) AdaPro GmbH. All rights reserved.
public sealed class QuestionController : PlatformController<CodeDOMSample.Question>
{
}
}
コンパイルされたコントローラーをMVCフレームワークに登録して、呼び出し /質問が「リソースが見つからない」で終わらないようにするにはどうすればよいですか?
問題はルートテーブルだとは思いません。
return RedirectToAction("Index", t.Name);
同様に機能しません。このためには、ルート登録は必要ないと思います。私が持っているルート登録は、かなり一般的で標準です。
routes.MapRoute(
"Default", // Routenname
"{controller}/{action}/{id}", // URL mit Parametern
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameterstandardwerte
);
MVCは、コントローラーが特定のディレクトリにあることを要求していることを覚えています - この場合はそうではありません。しかし、それは本当に奇妙なコンベンションです。 MVCはディレクトリ情報で何をしているのでしょうか?それはそれをスキャンし、私が信じているスタートアップで何らかの形でコントローラーを登録します。では、なぜ後で登録してはいけないのですか?唯一 - どのように?!?
また、問題はアセンブリだとは思いません。
私はこのコードを持っています:
// Invoke compilation.
CompilerResults cr = provider.CompileAssemblyFromDom(cp, cu);
Type t = cr.CompiledAssembly.GetExportedTypes().First();
return t;
コンパイルされたタイプを返します。だから、私はそれが編集後にすでにロードされていると思います。それ以外の場合は、Tは知られていないでしょう。また、出力ウィンドウで、ロードされていることがわかります。
解決
いくつかの提案: -
1)カスタムコントローラー工場を試してみてください(例を参照してください http://nayyeri.net/custom-controller-factory-in-asp-net-mvc)またはおそらくあなた自身のiroutehandlerの実装。 MVC 2には、フックできる多くの拡張性ポイントがあります。
2)MVC 2ソースをご覧ください。 TypeControllerCache
反射を使用してコントローラーを見つけます ロード アセンブリ。それがおそらくあなたのタイプが見つからない理由です。
他のヒント
おそらく、新しいアセンブリをAppDomainにロードする必要があります。