c# - Dynamic .NET WebAPI 5.2 Controllers based on some an abstract base type -


assuming rest , data access interactions standard, want able create abstract type represent entity objects pass , forth rest client (e.g. javascript in browser) persistence layer without writing/registering/routing bunch of different webapi controllers.

how can 1 create 1 controller base type implementation manage persistence of several different entity type rest interactions? i.e. how can make work webapi?

using system; using system.collections.generic; using system.diagnostics.contracts; using system.linq; using system.web; using system.web.http;  namespace dynamicentityapicontrollers {     /// <summary>     ///      /// </summary>     public class entitycontroller<t> : apicontroller         t : entityobject     {         private readonly idaoprovider daoprovider;          /// <summary>         /// initializes new instance of <see cref="entitycontroller{t}"/> class.         /// </summary>         /// <param name="daoprovider">the dao provider.</param>         protected entitycontroller(idaoprovider daoprovider)         {             this.daoprovider = daoprovider;         }          /// <summary>         /// gets name of collection.         /// </summary>         /// <value>         /// name of collection.         /// </value>         protected string collectionname         {                         {                 return (string)this.requestcontext.routedata.values["controller"];             }         }          /// <summary>         /// gets specified entity key collection.         /// </summary>         /// <param name="key">the key.</param>         /// <returns></returns>         public t get(string key)         {                         return this.daoprovider.output<t>(this.collectionname, key).data;         }          /// <summary>         /// creates or updates specified entity key in collection.         /// </summary>         /// <param name="key">the key.</param>         /// <param name="updating">the updating.</param>         /// <returns></returns>         public t put(string key, [frombody] t updating)         {             var daoobject = daoentity.create(this.collectionname, key, updating);             return this.daoprovider.input<t>(daoobject).data;         }          /// <summary>         /// creates or updates collection specified entirely.         /// </summary>         /// <param name="replacingcollection">the replacing collection.</param>         /// <returns></returns>         public ienumerable<t> put([frombody] ienumerable<t> replacingcollection)         {             return this.daoprovider.input<t>(replacingcollection                             .select(o => daoentity.create(this.collectionname, o)));         }          /// <summary>         /// creates new entity in specified collection.         /// </summary>         /// <param name="creating">the creating.</param>         /// <returns></returns>         public t post([frombody] t creating)         {             var daoentity = daoentity.create(this.collectionname, creating);             return this.daoprovider.input(daoentity).data;         }          /// <summary>         /// deletes specified entity key collection.         /// </summary>         /// <param name="key">the key.</param>         public void delete(string key)         {             this.daoprovider.delete(this.collectionname, key);         }     } } 

the javascript client must look/act this:

$.ajax({url: '/book', method: 'post', data: {title: 'this stackoverflow post', pagecount: '124' })     .done(function(data) {       $.get('/book/'+data.key).done(function(data) {          // return book created         console.dir(data);       })     })      $.ajax({url: '/book', method: 'post', data: {title: 'some other stackoverflow post', pagecount: '236' })     .done(function(data) {       $.get('/magazine/'+data.key).done(function(data) {          // return 404 status code because you're asking book's key          // in magazines collection         console.dir(data);       })     }) 

the sample solution has bunch todo here (like right etag header, if-match, etc...) had 4 queries across stackoverflow find these bits.

prerequisites:

  • autofac (ioc) integration webapi
  • webapi controller location / dependencyresolver (these not same things)
  • c# generics
  • reflection il emitting
  • very minimal rest understanding , etag is.

git source folder

briefly, here logic:

  • create base type (entityobject)
  • identify entities @ ioc registration time via reflection (implementer responsible specifying assemblies scan)
  • create concrete implementations of abstract class entitycontroller via il emitting
    • tell supportsdynamiccontrollertyperesolver these dynamic types
  • idaoprovider implementation "persistence" layer. implement persistence logic here.. in sample, in memory dictionary used.

and happens when request made: - routetable interrogated (finds {controller}/{key} route httproute - controller name matches entityobject implementer name minus entity. i.e. bookentity => bookcontroller - supportsdynamiccontrollertyperesolver required here dynamic assembly types valid candidates webapi try activate. - http put/get/post/delete methods find correct method - persistence layer rest


Comments

Popular posts from this blog

javascript - Jquery show_hide, what to add in order to make the page scroll to the bottom of the hidden field once button is clicked -

python - Django-cities exits with "killed" -

python - How to get a widget position inside it's layout in Kivy? -