Pergunta

I have some code that generates a model and a controller class:

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");
}

The controller code that is generated looks like this:

//------------------------------------------------------------------------------
// <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>
    {
    }
}

How can I register the compiled controller to the mvc framework, so that calling /Question will not end with "Resource can not be found"

I don't think the problem is the route table.

return RedirectToAction("Index", t.Name);

Does not work as well. I think for this no route registration is needed. The route registration I have is pretty generic and standard.

    routes.MapRoute(
        "Default", // Routenname
        "{controller}/{action}/{id}", // URL mit Parametern
        new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameterstandardwerte
    );

I remember that MVC requires the Controller to be in a certain directory - which in this case it is not. But is that really so strange a convention. I mean what does MVC do with the directory information? It does scan it and register the controller somehow at startup I believe. So why should I not register one later? Only - how?!?

Also I do not think the problem is the assembly.

I have this code:

// Invoke compilation. 
CompilerResults cr = provider.CompileAssemblyFromDom(cp, cu); 
Type t = cr.CompiledAssembly.GetExportedTypes().First(); 
return t; 

t returns the compiled type. So I assume it is already loaded after compilation. Otherwise t would not be known. Also I can see in the Output Window, that it is loaded.

Foi útil?

Solução

Some suggestions:-

1) Try a Custom Controller Factory (See e.g. http://nayyeri.net/custom-controller-factory-in-asp-net-mvc) or perhaps your own IRouteHandler implementation. MVC 2 has many extensibility points you could hook into.

2) Take a look at the MVC 2 sources. The TypeControllerCache finds controllers using reflection over the loaded assemblies. That's probably why it doesn't find your type.

Outras dicas

You'd probably have to load your new assembly into the AppDomain.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top