views:

36

answers:

2

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.

A: 

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

jfar
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.
Frank Michael Kraft
+1  A: 

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.

Hightechrider
Custom Controller Factory is the way to go.
Frank Michael Kraft