//--- Methods --- internal void Add(string[] path, int level, DreamFeature feature) { // check if we reached the last part of the feature path if (level == path.Length) { // add feature to signature map SignatureMap.Add(feature); } else { string key = path[level]; DreamFeatureDirectory entry = null; // check if sub-feature already exists if (Subfeatures.TryGetValue(key, out entry)) { entry.Add(path, level + 1, feature); } else { DreamFeatureDirectory tree = new DreamFeatureDirectory(); tree.Add(path, level + 1, feature); Subfeatures.Add(key, tree); } } }
//--- Constructors --- /// <summary> /// Create instance. /// </summary> /// <param name="env">Dream Environment.</param> /// <param name="verb">Http request verb.</param> /// <param name="uri">Request Uri.</param> /// <param name="feature">Request handling feature.</param> /// <param name="publicUri">Public Uri for incoming request.</param> /// <param name="serverUri">Server Uri for Dream Host.</param> /// <param name="request">Request message.</param> /// <param name="culture">Request Culture.</param> /// <param name="requestContainerFactory">Factory delegate to create a request container on demand.</param> public DreamContext(IDreamEnvironment env, string verb, XUri uri, DreamFeature feature, XUri publicUri, XUri serverUri, DreamMessage request, CultureInfo culture, Func <Action <ContainerBuilder>, ILifetimeScope> requestContainerFactory) { if (env == null) { throw new ArgumentNullException("env"); } if (verb == null) { throw new ArgumentNullException("verb"); } if (uri == null) { throw new ArgumentNullException("uri"); } if (feature == null) { throw new ArgumentNullException("feature"); } if (publicUri == null) { throw new ArgumentNullException("publicUri"); } if (request == null) { throw new ArgumentNullException("request"); } if (culture == null) { throw new ArgumentNullException("culture"); } if (requestContainerFactory == null) { throw new ArgumentNullException("requestContainerFactory"); } this.ID = System.Threading.Interlocked.Increment(ref _contextIdCounter); this.Env = env; this.Verb = verb; this.Uri = uri; this.Feature = feature; this.Feature.ExtractArguments(this.Uri, out _suffixes, out _pathParams); this.ServerUri = serverUri; this.Request = request; this.StartTime = GlobalClock.UtcNow; _publicUri = publicUri; _culture = culture; _requestContainerFactory = requestContainerFactory; // get service license _license = CheckServiceLicense(); }
private DreamContext(IDreamEnvironment env, string verb, XUri uri, DreamFeature feature, XUri publicUri, XUri serverUri, DreamMessage request, CultureInfo culture, Func <IContainer> requestContainerFactory, Dictionary <string, string> license) { if (env == null) { throw new ArgumentNullException("env"); } if (verb == null) { throw new ArgumentNullException("verb"); } if (uri == null) { throw new ArgumentNullException("uri"); } if (feature == null) { throw new ArgumentNullException("feature"); } if (publicUri == null) { throw new ArgumentNullException("publicUri"); } if (request == null) { throw new ArgumentNullException("request"); } if (culture == null) { throw new ArgumentNullException("culture"); } if (requestContainerFactory == null) { throw new ArgumentNullException("requestContainerFactory"); } this.ID = System.Threading.Interlocked.Increment(ref _contextIdCounter); this.Env = env; this.Verb = verb; this.Uri = uri; this.Feature = feature; this.Feature.ExtractArguments(this.Uri, out _suffixes, out _pathParams); this.ServerUri = serverUri; this.Request = request; this.StartTime = DateTime.UtcNow; _publicUri = publicUri; _culture = culture; _requestContainerFactory = requestContainerFactory; _license = license; }
//--- Methods --- internal void Add(string[] path, int level, DreamFeature feature) { // check if we reached the last part of the feature path if(level == path.Length) { // add feature to signature map SignatureMap.Add(feature); } else { string key = path[level]; DreamFeatureDirectory entry = null; // check if sub-feature already exists if(Subfeatures.TryGetValue(key, out entry)) { entry.Add(path, level + 1, feature); } else { DreamFeatureDirectory tree = new DreamFeatureDirectory(); tree.Add(path, level + 1, feature); Subfeatures.Add(key, tree); } } }
internal DreamContext CreateContext(string verb, XUri uri, DreamFeature feature, DreamMessage message) { return(new DreamContext(Env, verb, uri, feature, PublicUri, ServerUri, message, Culture, _requestContainerFactory, null)); }
private DreamFeatureDirectory CreateServiceFeatureDirectory(IDreamService service, XDoc blueprint, XDoc config) { Type type = service.GetType(); string path = config["path"].Contents.ToLowerInvariant(); // add transport information XUri serviceUri = LocalMachineUri.AtAbsolutePath(path); config.Root.Elem("uri.self", serviceUri.ToString()); // compile list of active service features, combined by suffix int serviceUriSegmentsLength = serviceUri.Segments.Length; DreamFeatureDirectory directory = new DreamFeatureDirectory(); var methodInfos = GetMethodInfos(type); foreach(XDoc featureBlueprint in blueprint["features/feature"]) { string methodName = featureBlueprint["method"].Contents; string pattern = featureBlueprint["pattern"].AsText; // TODO (steveb): we should be a little more discerning here as this might trigger false positives bool atConfig = pattern.ContainsInvariantIgnoreCase("@config"); // locate method var methods = methodInfos[methodName]; if(methods.Count() > 1) { var found = string.Join(", ", methods.Select(m => m.DeclaringType.FullName + "!" + m.Name + "(" + string.Join(", ", m.GetParameters().Select(p => p.ParameterType.Name + " " + p.Name).ToArray()) + ")").ToArray()); throw new MissingMethodException(string.Format("found multiple definitions for {0}: {1}", methodName, found)); } if(methods.None()) { throw new MissingMethodException(string.Format("could not find {0} in class {1}", methodName, type.FullName)); } MethodInfo method = methods.First(); // determine access level DreamAccess access; switch(featureBlueprint["access"].AsText) { case null: case "public": access = DreamAccess.Public; break; case "internal": access = DreamAccess.Internal; break; case "private": access = DreamAccess.Private; break; default: throw new NotSupportedException(string.Format("access level is not supported ({0})", methodName)); } // parse pattern string string[] parts = pattern.Split(new[] { ':' }, 2); string verb = parts[0].Trim(); string signature = parts[1].Trim(); if(signature.Length == 0) { signature = string.Empty; } // add feature prologues List<DreamFeatureStage> stages = new List<DreamFeatureStage>(); stages.AddRange(_defaultPrologues); if(!atConfig) { DreamFeatureStage[] custom = service.Prologues; if(!ArrayUtil.IsNullOrEmpty(custom)) { stages.AddRange(custom); } } // add feature handler int mainStageIndex = stages.Count; stages.Add(new DreamFeatureStage(service, method, access)); // add feature epilogues if(!atConfig) { DreamFeatureStage[] custom = service.Epilogues; if(!ArrayUtil.IsNullOrEmpty(custom)) { stages.AddRange(custom); } } stages.AddRange(_defaultEpilogues); // create dream feature and add to service directory var paramAttributes = method.GetCustomAttributes(typeof(DreamFeatureParamAttribute), false).Cast<DreamFeatureParamAttribute>().ToArray(); DreamFeature feature = new DreamFeature(service, serviceUri, mainStageIndex, stages.ToArray(), verb, signature, paramAttributes); directory.Add(feature.PathSegments, serviceUriSegmentsLength, feature); } return directory; }