public string GetVirtualPath(ISTKService srv, MethodInfo mi, RouteValueDictionary args) { if (_resolvVirtualPathContext == null) { var factory = _host.Services.GetService <IHttpContextFactory>(); _resolvVirtualPathContext = factory.Create(_host.ServerFeatures); } var vpc = new VirtualPathContext(_resolvVirtualPathContext, null, args, $"{srv.Alias}-{mi.Name}"); var path = _router.GetVirtualPath(vpc).VirtualPath; return(""); }
public void ResolveRouter(ISTKService srv) { ServiceRouteCollection routers = new ServiceRouteCollection(); var inlineResolver = _host.Services.GetService <IInlineConstraintResolver>(); Type srvType = srv.GetType(); foreach (var methodInfo in srvType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) { Action <HttpContext> func = null; foreach (var info in methodInfo.GetCustomAttributes(false).OfType <RouteAttribute>()) { var routeName = $"{srv.Alias}-{methodInfo.Name}"; var templateStr = MixRoute(srv.Alias, info.Template); if (func == null) { func = BuildHandler(methodInfo, srv, templateStr); } var constraints = new RouteValueDictionary(new { httpMethod = new HttpMethodRouteConstraint(info.Verb) }); var route = new Route( new RouteHandler(context => { var ret = new Task(() => { try { func(context); } catch (Exception e) { Console.WriteLine(e); } }); ret.Start(); return(ret); }), routeName: routeName, routeTemplate: templateStr, defaults: null, constraints: constraints, dataTokens: null, inlineConstraintResolver: inlineResolver); routers.Add(route); } } routers.Service = srv; _router.Add(routers); }
public void RemoveRoute(ISTKService srv) { _router.RemoveRouting(srv); }
/// <summary> /// 读取配置Xml文档 /// 格式类似下面的: /// <STKProject> /// <Services> /// <Service Class="NetEaseFetch"> /// <!--Settings Of NetEaseFetch Service--> /// </Service> /// </Services> /// <Connections> /// <Connection> /// <From>Alias.Method</From> /// <To>Alias.Port</To> /// </Connection> /// </Connections> /// </STKProject> /// </summary> /// <param name="xmlPath"></param> public void ReadSetting(string xmlPath) { var doc = XDocument.Load(xmlPath); var root = doc.Element("STKProject"); if (root == null) { return; } if (root.Element("Services") == null) { return; } if (root.Element("Connections") == null) { return; } foreach (var xElement in root.Element("Services").Elements("Service")) { string className = xElement.Attribute("Class")?.Value; if (className == null) { continue; } Type classType = null; ServiceTypes.TryGetValue(className, out classType); if (classType == null) { throw new ArgumentException("不存在服务:" + className); } ISTKService srv = (ISTKService)Activator.CreateInstance(classType); srv.LoadDefaultSetting();//Load Default Setting First foreach (var element in xElement.Elements()) { var propInfo = classType.GetProperty(element.Name.ToString()); if (propInfo == null) { continue; } propInfo.SetValue(srv, Convert.ChangeType(element.Value, propInfo.PropertyType)); } ActiveServices.Add(srv); } foreach (var xElement in root.Element("Connections").Elements("Connection")) { var from = xElement.Element("From").Value.Split('.'); var to = xElement.Element("To").Value.Split('.'); string fromAlias = from[0]; string fromMethod = from[1]; string toAlias = to[0]; string toPort = to[1]; ISTKService fromSrv; ISTKService toSrv; if ((fromSrv = ActiveServices.FirstOrDefault(srv => srv.Alias == fromAlias)) == null) { throw new Exception("找不到" + fromAlias); } if ((toSrv = ActiveServices.FirstOrDefault(srv => srv.Alias == toAlias)) == null) { throw new Exception("找不到" + toSrv); } var fromType = fromSrv.GetType(); var toType = toSrv.GetType(); var fromMethodInfo = fromType.GetMethod(fromMethod); var toPortInfo = toType.GetProperty(toPort); var fromArgs = fromMethodInfo.GetParameters().Select(parameter => parameter.ParameterType).ToArray(); //https://stackoverflow.com/questions/12131301/how-can-i-dynamically-create-an-actiont-at-runtime //动态创建类型 var fromMethodType = fromArgs.Length > 0 ? _actionTypes[fromArgs.Length].MakeGenericType(fromArgs) :typeof(Action); if (toPortInfo.PropertyType != fromMethodType) { Console.WriteLine(toPortInfo.PropertyType.ToString() + fromType + "is Not Equal"); continue; } var fromMethodDelegate = Delegate.CreateDelegate(fromMethodType, fromSrv, fromMethodInfo, true); var toPortValue = (Delegate)toPortInfo.GetValue(toSrv); var finalDelegate = Delegate.Combine(fromMethodDelegate, toPortValue); toPortInfo.SetValue(toSrv, finalDelegate); //https://stackoverflow.com/questions/3016429/reflection-and-operator-overloads-in-c-sharp //获取运算符重载 //var toPortBindFunc = fromMethodType.GetMethod("op_AdditionAssignment"); //toPortBindFunc.Invoke(toPortInfo, new Object[]{fromMethodDelegate}); } }