internal void InitializeServices() { string servicesAttribute = (string)Document.Body.GetAttribute("data-services"); if (String.IsNullOrEmpty(servicesAttribute)) { return; } string[] serviceNames = servicesAttribute.Split(","); int serviceCount = serviceNames.Length; if (serviceCount != 0) { for (int i = 0; i < serviceCount; i++) { string name = serviceNames[i]; ServiceRegistration registration = _registeredServices[name]; Debug.Assert(registration != null, "Unknown service '" + name + "'"); object service = GetObject(registration.ServiceImplementationType); IService initializableService = service as IService; if (initializableService != null) { Dictionary <string, object> options = OptionsParser.GetOptions(Document.Body, name); initializableService.Initialize(options); } RegisterObject(registration.ServiceType, service); } } }
/// <summary> /// Creates and attaches behaviors specified on the element declaratively. /// </summary> /// <param name="element">The element whose behaviors should be created and attached.</param> private void AttachBehaviors(Element element) { string[] behaviorNames = ((string)element.GetAttribute(Application.BehaviorsAttribute)).Split(","); int behaviorCount = behaviorNames.Length; for (int i = 0; i < behaviorCount; i++) { string name = behaviorNames[i].Trim(); BehaviorRegistration registration = _registeredBehaviors[name]; Debug.Assert(registration != null, "Unknown behavior '" + name + "'"); if (registration != null) { Dictionary <string, object> options = OptionsParser.GetOptions(element, name); // Use the Application's IoC capabilities to create behaviors. // This allows satisfying dependencies behaviors have to other services, // and also allows behaviors to provide or register services into the container. Behavior behavior = (Behavior)GetObject(registration.BehaviorType); behavior.Initialize(element, options); if (registration.ServiceType != null) { // Special-case the common case where a behavior represents a single // service type, and auto-register it. // In the case where a behavior is registering multiple service types // (not so common), it can do so manually in its Initialize method. RegisterObject(registration.ServiceType, behavior); } } } }
/// <summary> /// Gets a template instance from the specified template name. The specified name /// is used to lookup a script element with a matching id. /// </summary> /// <param name="name">The name to lookup a template.</param> /// <returns>The template instance if the associated element could be found and successfully parsed.</returns> public Template GetTemplate(string name) { Debug.Assert(String.IsNullOrEmpty(name) == false); // TODO: Should we allow plugging in a template selector callback? // We would need to have a value parameter to pass in the data value into GetTemplate. // Check if there is a previously parsed or registered template Template template = _registeredTemplates[name]; if (template != null) { return(template); } Element templateElement = Document.GetElementById(name); Debug.Assert(templateElement != null, "Could not find a template element with the id '" + name + "'."); if (templateElement == null) { return(null); } // Parse the template using the associated template engine string templateType = (string)templateElement.GetAttribute(TemplateTypeAttribute); Debug.Assert(String.IsNullOrEmpty(templateType) == false, "A template must have a valid data-template attribute set."); template = CompileTemplate(templateType, templateElement.TextContent, OptionsParser.GetOptions(templateElement, TemplateOptionsAttribute)); // Cache the newly parsed template for future use _registeredTemplates[name] = template; return(template); }
private void SetupServices() { string servicesAttribute = (string)Document.Body.GetAttribute(ServicesAttribute); if (String.IsNullOrEmpty(servicesAttribute)) { return; } string[] serviceNames = servicesAttribute.Split(","); int serviceCount = serviceNames.Length; for (int i = 0; i < serviceCount; i++) { string name = serviceNames[i]; ServiceRegistration registration = _registeredServices[name]; Debug.Assert(registration != null, "Unknown service '" + name + "'"); // TODO: Add support for deferred loading of service implementation, where // the service gets included later, even though it is declared at the // page level. object service = GetObject(registration.ServiceImplementationType); IInitializable initializableService = service as IInitializable; if (initializableService != null) { Dictionary <string, object> options = OptionsParser.GetOptions(Document.Body, name); initializableService.BeginInitialization(options); initializableService.EndInitialization(); } RegisterObject(registration.ServiceType, service); } }
/// <summary> /// Activates a specified element and its children by instantiating any /// declaratively specified behaviors or bindings within the markup. /// </summary> /// <param name="element">The element to activate.</param> /// <param name="contentOnly">Whether the element should be activated, or only its contained content.</param> /// <param name="model">The model to bind to.</param> public void ActivateFragment(Element element, bool contentOnly, object model) { Debug.Assert(element != null); if (element == Document.Body) { // Perform app-level activation (tied to body initialization) // Setup top-level services specified declaratively. SetupServices(); // Create the model declaratively associated with the application. if (model == null) { string modelTypeName = (string)Document.Body.GetAttribute(ModelTypeAttribute); if (String.IsNullOrEmpty(modelTypeName) == false) { Type modelType = Type.GetType(modelTypeName); Debug.Assert(modelType != null, "Could not resolve model '" + modelTypeName + "'"); model = GetObject(modelType); IInitializable initializableModel = model as IInitializable; if (initializableModel != null) { Dictionary <string, object> modelData = OptionsParser.GetOptions(element, "model"); initializableModel.BeginInitialization(modelData); initializableModel.EndInitialization(); } } } _model = model; } // Create expressions and bindings associated with the specified elements and // the contained elements. Do this first, as this allows behaviors to look at // values set as a result of bindings when they are attached. if ((contentOnly == false) && element.HasAttribute(Application.BindingsAttribute)) { SetupBindings(element, model); } ElementCollection boundElements = element.QuerySelectorAll(Application.BindingsSelector); for (int i = 0, boundElementCount = boundElements.Length; i < boundElementCount; i++) { SetupBindings(boundElements[i], model); } // Attach behaviors associated declaratively with the specified element and the // contained elements. if ((contentOnly == false) && element.HasAttribute(Application.BehaviorsAttribute)) { AttachBehaviors(element); } ElementCollection extendedElements = element.QuerySelectorAll(Application.BehaviorsSelector); for (int i = 0, extendedElementCount = extendedElements.Length; i < extendedElementCount; i++) { AttachBehaviors(extendedElements[i]); } }