Advertisement
Guest User

Untitled

a guest
Dec 18th, 2015
347
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 7.43 KB | None | 0 0
  1. public interface IBusinessProxyController<out TBusinessImplementation> : IHttpController
  2.         where TBusinessImplementation : IBusinessImplementation
  3.     {
  4.         TBusinessImplementation BusinessImplementation { get; }
  5.         ModelStateDictionary ModelState { get; }
  6.     }
  7.     public class BusinessProxyController<TBusinessImplementation> : ApiController, IBusinessProxyController<TBusinessImplementation>
  8.         where TBusinessImplementation : IBusinessImplementation
  9.     {
  10.         public BusinessProxyController(TBusinessImplementation business)
  11.         {
  12.             this.BusinessImplementation = business;
  13.         }
  14.         public TBusinessImplementation BusinessImplementation
  15.         {
  16.             get;
  17.             private set;
  18.         }
  19.     }
  20.  
  21.     public static class BusinessProxyControllerFactory
  22.     {
  23.         public static void Register<TBusinessProxyController, TBusinessImplementation>(IUnityContainer container, RouteCollection routes, string name, string path = "api", params Expression<Func<TBusinessImplementation, dynamic>>[] ignoreAction)
  24.             where TBusinessProxyController : IBusinessProxyController<TBusinessImplementation>
  25.             where TBusinessImplementation : IBusinessImplementation
  26.         {
  27.             container.RegisterType<IHttpController, TBusinessProxyController>(name.ToLower());
  28.             var controller = container.Resolve<TBusinessProxyController>();
  29.             var methods = controller.BusinessImplementation.GetType().GetMethodsCached(BindingFlags.Public | BindingFlags.Instance);
  30.             var interfaceMethods = controller.BusinessImplementation.GetType().GetInterfacesCached().SelectMany(i => i.GetMethodsCached(BindingFlags.Public | BindingFlags.Instance)).ToArray();
  31.             var ignoreMethods = ignoreAction.Select(a =>
  32.             {
  33.                 var methodCall = a.Body as MethodCallExpression;
  34.                 if (methodCall != null)
  35.                     return new Tuple<MethodInfo, ServiceMethod>(methodCall.Method, methodCall.Method.GetCustomAttributeCached<ServiceMethod>(true));
  36.                 throw new ArgumentException("Ignore action must be a method call");
  37.             });
  38.             var serviceMethodRouts = methods.SelectMany(m => m.GetCustomAttributesCached<ServiceRoute>(true).Select(
  39.                 r => new Tuple<MethodInfo, ServiceRoute, ServiceMethod>(m, r, m.GetCustomAttributeCached<ServiceMethod>(true)))).Union(
  40.                     interfaceMethods.SelectMany(i => i.GetCustomAttributesCached<ServiceRoute>(true).Select(r => new Tuple<MethodInfo, ServiceRoute, ServiceMethod>(i, r, i.GetCustomAttributeCached<ServiceMethod>(true)))), new RouteComparer()).Where(
  41.                         m => !ignoreMethods.Any(im => im.Item1.Name == m.Item1.Name && im.Item2.MethodType == m.Item3.MethodType));
  42.             foreach (var pritoryGroup in serviceMethodRouts.GroupBy(r => (int)r.Item2.Priority).OrderBy(g => g.Key))
  43.             {
  44.                 var levelLookup = pritoryGroup.ToLookup(p => p.Item2.IdPathMapping.Length);
  45.                 RegisterRoutes(routes, name, path, levelLookup);
  46.             }
  47.         }
  48.         private static void RegisterRoutes(RouteCollection routes, string name, string path, ILookup<int, Tuple<MethodInfo, ServiceRoute, ServiceMethod>> levelGroup, int? maxLevel = null, int level = 1)
  49.         {
  50.             if (maxLevel == null)
  51.                 maxLevel = levelGroup.Max(g => g.Key);
  52.             foreach (var pathGroup in levelGroup.Where(l => l.Key >= level).SelectMany(g => g).GroupBy(g => g.Item2.IdPathMapping[level - 1]).OrderBy(g => g.Key))
  53.             {
  54.                 if (level < maxLevel)
  55.                 {
  56.                     var greaterThanGroup = pathGroup.Where(g => g.Item2.IdPathMapping.Length > level).ToLookup(g => g.Item2.IdPathMapping.Length);
  57.                     RegisterRoutes(routes, name, path, greaterThanGroup, maxLevel, level + 1);
  58.                 }
  59.                 foreach (var route in pathGroup.Where(g => g.Item2.IdPathMapping.Length == level).OrderBy(g => g.Item2.IdPathMapping[level - 1]))
  60.                 {
  61.                     routes.MapHttpRoute(string.Format("{0}{1}", name.ToLower(), route.Item2.Key),
  62.                                 string.Format("{0}/{1}/{2}", path, name, route.Item2.RoutePath),
  63.                                 new { controller = name.ToLower(), action = route.Item1.Name },
  64.                                 constraints: new { httpMethod = new HttpMethodConstraint(route.Item3.ToHttpMethod().Method, HttpMethod.Options.Method) });
  65.                 }
  66.             }
  67.         }
  68.         public static void Register<TBusinessProxyController, TBusinessImplementation, TView>(IUnityContainer container, RouteCollection routes, string name = null, string path = "api", params Expression<Func<TBusinessImplementation, dynamic>>[] ignoreAction)
  69.             where TBusinessProxyController : IBusinessProxyController<TBusinessImplementation>
  70.             where TBusinessImplementation : IBusinessImplementation
  71.         {
  72.             if (name == null)
  73.             {
  74.                 name = GetViewName<TBusinessImplementation>();
  75.                 if (name == null)
  76.                     name = typeof(TView).Name.Pluralize();
  77.             }
  78.             Register<TBusinessProxyController, TBusinessImplementation>(container, routes, name, path, ignoreAction);
  79.         }
  80.         public static void RegisterDefault<TBusinessImplementation, TView>(IUnityContainer container, RouteCollection routes, string name = null, string path = "api", params Expression<Func<TBusinessImplementation, dynamic>>[] ignoreAction)
  81.             where TBusinessImplementation : IBusinessImplementation
  82.         {
  83.             Register<BusinessProxyController<TBusinessImplementation>, TBusinessImplementation, TView>(container, routes, name, path, ignoreAction);
  84.         }
  85.         public static void RegisterDefault<TBusinessImplementation>(IUnityContainer container, RouteCollection routes, string name = null, string path = "api", params Expression<Func<TBusinessImplementation, dynamic>>[] ignoreAction)
  86.             where TBusinessImplementation : IBusinessImplementation
  87.         {
  88.             if (name == null)
  89.                 name = GetViewName<TBusinessImplementation>();
  90.             if (name == null)
  91.                 throw new ArgumentException("Name was not provided and the business implemention does not have a name on the ServiceAttribute");
  92.             Register<BusinessProxyController<TBusinessImplementation>, TBusinessImplementation>(container, routes, name, path, ignoreAction);
  93.         }
  94.         private static string GetViewName<TBusinessImplemention>()
  95.             where TBusinessImplemention : IBusinessImplementation
  96.         {
  97.             var serviceAttr = typeof(TBusinessImplemention).GetCustomAttributeCached<ServiceAttribute>(true);
  98.             if (serviceAttr == null)
  99.                 return null;
  100.             return serviceAttr.Name;
  101.         }
  102.         private class RouteComparer : IEqualityComparer<Tuple<MethodInfo, ServiceRoute, ServiceMethod>>
  103.         {
  104.             public bool Equals(Tuple<MethodInfo, ServiceRoute, ServiceMethod> x, Tuple<MethodInfo, ServiceRoute, ServiceMethod> y)
  105.             {
  106.                 return x.Item2.Key == y.Item2.Key && x.Item3.MethodType == y.Item3.MethodType;
  107.             }
  108.             public int GetHashCode(Tuple<MethodInfo, ServiceRoute, ServiceMethod> obj)
  109.             {
  110.                 return HashCodeProvider.BuildHashCode(obj.Item2.Key, obj.Item3.MethodType);
  111.             }
  112.         }
  113.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement