2010-08-05 17 views
12

Ich denke über die Implementierung eines generischen Controllers in ASP.NET MVC.asp.net mvc generischer Controller

wobei T ein (generiertes) Plattformobjekt ist.

Ist das möglich? Gibt es Erfahrung/Dokumentation?

Eine verwandte Frage zum Beispiel ist, wie die resultierenden URLs sind.

+0

Sie haben würden Routen für jedes 'T' konfigurieren ... oder eine Lookup-Magie zur Laufzeit durchführen. Es gibt Auswirkungen auf die Leistung, aber ansonsten scheint es eine gute Idee zu sein. – bzlm

Antwort

18

ja es ist, kann man einfach nicht direkt verwenden, aber man kann es erben und verwenden Sie die Childs

hier ist eine, die ich benutze:

 public class Cruder<TEntity, TInput> : Controller 
     where TInput : new() 
     where TEntity : new() 
    { 
     protected readonly IRepo<TEntity> repo; 
     private readonly IBuilder<TEntity, TInput> builder; 


     public Cruder(IRepo<TEntity> repo, IBuilder<TEntity, TInput> builder) 
     { 
      this.repo = repo; 
      this.builder = builder; 
     } 

     public virtual ActionResult Index(int? page) 
     { 
      return View(repo.GetPageable(page ?? 1, 5)); 
     } 

     public ActionResult Create() 
     { 
      return View(builder.BuildInput(new TEntity())); 
     } 

     [HttpPost] 
     public ActionResult Create(TInput o) 
     { 
      if (!ModelState.IsValid) 
       return View(o); 
      repo.Insert(builder.BuilEntity(o)); 
      return RedirectToAction("index"); 
     } 
    } 

und Verwendungen:

public class FieldController : Cruder<Field,FieldInput> 
    { 
     public FieldController(IRepo<Field> repo, IBuilder<Field, FieldInput> builder) 
      : base(repo, builder) 
     { 
     } 
    } 

    public class MeasureController : Cruder<Measure, MeasureInput> 
    { 
     public MeasureController(IRepo<Measure> repo, IBuilder<Measure, MeasureInput> builder) : base(repo, builder) 
     { 
     } 
    } 

    public class DistrictController : Cruder<District, DistrictInput> 
    { 
     public DistrictController(IRepo<District> repo, IBuilder<District, DistrictInput> builder) : base(repo, builder) 
     { 
     } 
    } 

    public class PerfecterController : Cruder<Perfecter, PerfecterInput> 
    { 
     public PerfecterController(IRepo<Perfecter> repo, IBuilder<Perfecter, PerfecterInput> builder) : base(repo, builder) 
     { 
     } 
    } 

ist der Code hier: http://code.google.com/p/asms-md/source/browse/trunk/WebUI/Controllers/FieldController.cs

Update:

diesen Ansatz jetzt hier: http://prodinner.codeplex.com

+0

Ok - so ist mein Problem lösbar. Wenn der Typ für den Typparameter generiert wird und der Basiscontroller generisch implementiert ist, muss ich nur den abgeleiteten Controller für jeden Typ generieren, den ich als Typparameter verwenden möchte. Das ist so einfach wie möglich. Cool! –