/// <summary> /// Notifies this extension component that it has been registered in the owner's collection of extensions. /// </summary> /// <param name="owner">The extensible owner object that aggregates this extension.</param> public void Attach(IExtensibleCloudServiceComponent owner) { owner.EnsureExists <RulesEngineServiceClientExtension>(); owner.EnsureExists <ActivityTrackingEventStreamExtension>(); this.owner = owner; }
/// <summary> /// Notifies this extension component that it has been unregistered from the owner's collection of extensions. /// </summary> /// <param name="owner">The extensible owner object that aggregates this extension.</param> public void Detach(IExtensibleCloudServiceComponent owner) { if (this.diagnosticMonitor != null) { this.diagnosticMonitor.Shutdown(); } }
/// <summary> /// Notifies this extension component that it has been registered in the owner's collection of extensions. /// </summary> /// <param name="owner">The extensible owner object that aggregates this extension.</param> public void Attach(IExtensibleCloudServiceComponent owner) { if (null == this.transformCache) { this.transformCache = new ConcurrentDictionary <string, XslTransformCacheItemInfo>(); } }
/// <summary> /// Notifies this extension component that it has been registered in the owner's collection of extensions. /// </summary> /// <param name="owner">The extensible owner object that aggregates this extension.</param> public void Attach(IExtensibleCloudServiceComponent owner) { owner.Extensions.Demand <IRoleConfigurationSettingsExtension>(); this.roleConfigExtension = owner.Extensions.Find <IRoleConfigurationSettingsExtension>(); this.communicationRetryPolicy = this.roleConfigExtension.CommunicationRetryPolicy; }
/// <summary> /// Notifies this extension component that it has been registered in the owner's collection of extensions. /// </summary> /// <param name="owner">The extensible owner object that aggregates this extension.</param> public void Attach(IExtensibleCloudServiceComponent owner) { owner.Extensions.Demand <IRoleConfigurationSettingsExtension>(); IRoleConfigurationSettingsExtension roleConfigExtension = owner.Extensions.Find <IRoleConfigurationSettingsExtension>(); this.settings = new WorkItemProcessorConfigurationSettings(roleConfigExtension.GetSection <ApplicationConfigurationSettings>(WorkItemProcessorConfigurationSettings.SectionName)); }
/// <summary> /// Notifies this extension component that it has been unregistered from the owner's collection of extensions. /// </summary> /// <param name="owner">The extensible owner object that aggregates this extension.</param> public void Detach(IExtensibleCloudServiceComponent owner) { this.subscribers.Clear(); if (this.cts != null) { this.cts.Cancel(); // Wait for receive operation to complete gracefully. if (this.receiveHandle != null) { this.receiveHandle.AsyncWaitHandle.WaitOne(this.settings.EventWaitTimeout); this.receiveHandle = null; } this.cts.Dispose(); } if (this.ircEventSender != null) { this.ircEventSender.SafeClose(); this.ircEventSender = null; } if (this.ircEventReceiver != null) { this.ircEventReceiver.SafeClose(); this.ircEventReceiver = null; } if (this.topicClient != null) { this.topicClient.SafeClose(); this.topicClient = null; } if (this.subscriptionClient != null) { this.subscriptionClient.SafeClose(); this.subscriptionClient = null; } if (this.messagingFactory != null) { this.messagingFactory.SafeClose(); this.messagingFactory = null; } if (this.ircSubscription != null) { try { RemoveSubscription(this.ircSubscription); } catch { // We should not fail while disposing. } } }
/// <summary> /// Notifies this extension component that it has been unregistered from the owner's collection of extensions. /// </summary> /// <param name="owner">The extensible owner object that aggregates this extension.</param> public void Detach(IExtensibleCloudServiceComponent owner) { var callToken = TraceManager.WorkerRoleComponent.TraceIn(this.queueLocation.StorageAccount, this.queueLocation.QueueName); try { // Communicate a request for cancellation of all running dequeue tasks. cancellationSignal.Cancel(); foreach (var task in this.dequeueTasks) { var taskStopScopeStart = TraceManager.WorkerRoleComponent.TraceStartScope(String.Format(CultureInfo.CurrentCulture, TraceLogMessages.ScopeCloudQueueListenerExtensionStopDequeueTask, task.Id, task.Status), callToken); try { // Block until the task completes (if it's running). if (task.Status != TaskStatus.Canceled && task.Status != TaskStatus.Faulted && task.Status != TaskStatus.RanToCompletion) { task.Wait(); } } catch (AggregateException) { // Should ensure a safe stop, just ignore this exception and don't let it damage the rest of the Detach logic. } catch (OperationCanceledException) { // Should ensure a safe stop, just ignore this exception and don't let it damage the rest of the Detach logic. } catch (Exception ex) { // Should ensure a safe stop, just log an exception and don't let it damage the rest of the Detach logic. TraceManager.WorkerRoleComponent.TraceError(ex); } finally { TraceManager.WorkerRoleComponent.TraceEndScope(String.Format(CultureInfo.CurrentCulture, TraceLogMessages.ScopeCloudQueueListenerExtensionStopDequeueTask, task.Id, task.Status), taskStopScopeStart, callToken); task.Dispose(); } } if (this.subscriptions != null) { this.subscriptions.Dispose(); this.subscriptions = null; } if (this.queueStorage != null) { this.queueStorage.Dispose(); this.queueStorage = null; } } finally { TraceManager.WorkerRoleComponent.TraceOut(callToken); } }
/// <summary> /// Notifies this extension component that it has been unregistered from the owner's collection of extensions. /// </summary> /// <param name="owner">The extensible owner object that aggregates this extension.</param> public void Detach(IExtensibleCloudServiceComponent owner) { if (this.publisher != null) { this.publisher.Dispose(); this.publisher = null; } }
/// <summary> /// Notifies this extension component that it has been unregistered from the owner's collection of extensions. /// </summary> /// <param name="owner">The extensible owner object that aggregates this extension.</param> public void Detach(IExtensibleCloudServiceComponent owner) { if (this.transformCache != null) { this.transformCache.Clear(); this.transformCache = null; } }
/// <summary> /// Notifies this extension component that it has been registered in the owner's collection of extensions. /// </summary> /// <param name="owner">The extensible owner object that aggregates this extension.</param> public void Attach(IExtensibleCloudServiceComponent owner) { IRoleConfigurationSettingsExtension roleConfigExtension = owner.Extensions.Find <IRoleConfigurationSettingsExtension>(); if (roleConfigExtension != null) { this.activityTrackingClient = new ReliableServiceBusClient <IActivityTrackingServiceChannel>(roleConfigExtension.OnPremiseRelayOneWayEndpoint, roleConfigExtension.CommunicationRetryPolicy); } }
/// <summary> /// Notifies this extension component that it has been unregistered from the owner's collection of extensions. /// </summary> /// <param name="owner">The extensible owner object that aggregates this extension.</param> public void Detach(IExtensibleCloudServiceComponent owner) { if (this.discoveryClientRegistration != null) { this.discoveryClientRegistration.Dispose(); } this.discoveryActions.Clear(); }
/// <summary> /// Notifies this extension component that it has been registered in the owner's collection of extensions. /// </summary> /// <param name="owner">The extensible owner object that aggregates this extension.</param> public void Attach(IExtensibleCloudServiceComponent owner) { owner.Extensions.Demand <ICloudStorageProviderExtension>(); owner.Extensions.Demand <ICloudStorageLoadBalancingExtension>(); owner.Extensions.Demand <IXslTransformProviderExtension>(); this.cloudStorageProvider = owner.Extensions.Find <ICloudStorageProviderExtension>(); this.cloudStorageLoadBalancer = owner.Extensions.Find <ICloudStorageLoadBalancingExtension>(); this.transformProvider = owner.Extensions.Find <IXslTransformProviderExtension>(); }
/// <summary> /// Notifies this extension component that it has been registered in the owner's collection of extensions. /// </summary> /// <param name="owner">The extensible owner object that aggregates this extension.</param> public void Attach(IExtensibleCloudServiceComponent owner) { owner.Extensions.Demand <IWorkItemProcessorConfigurationExtension>(); owner.Extensions.Demand <IRoleConfigurationSettingsExtension>(); owner.Extensions.Demand <ICloudCacheProviderExtension>(); owner.Extensions.Demand <IRulesEngineServiceClientExtension>(); this.configSettingsExtension = owner.Extensions.Find <IWorkItemProcessorConfigurationExtension>(); this.roleConfigExtension = owner.Extensions.Find <IRoleConfigurationSettingsExtension>(); this.cacheProviderExtension = owner.Extensions.Find <ICloudCacheProviderExtension>(); this.rulesEngineExtension = owner.Extensions.Find <IRulesEngineServiceClientExtension>(); }
/// <summary> /// Verifies whether or not the specified extension type exists in the extension collection. If not found, the extension will be /// automatically instantiated and added into the underlying collection. /// </summary> /// <typeparam name="T">The type of the extension. Must implement <see cref="System.ServiceModel.IExtension<T>"/> as prescribed by the extension model.</typeparam> /// <param name="instance">The instance of the object implementing the <see cref="IExtensibleCloudServiceComponent"/> interface.</param> public static void EnsureExists <T>(this IExtensibleCloudServiceComponent instance) where T : ICloudServiceComponentExtension, new() { if (null == instance.Extensions.Find <T>()) { lock (instance) { if (null == instance.Extensions.Find <T>()) { instance.Extensions.Add(new T()); } } } }
private void ConfigureServiceHostWorkerRole(IExtensibleCloudServiceComponent ownerRole) { var callToken = TraceManager.WorkerRoleComponent.TraceIn(ownerRole != null ? ownerRole.GetType().FullName : null); var startScopeCreateServiceHosts = TraceManager.WorkerRoleComponent.TraceStartScope(TraceLogMessages.ScopeCreateServiceHosts, callToken); if (ownerRole != null) { IList <ServiceBusHostWorkerRoleAttribute> serviceHostAttributes = FrameworkUtility.GetDeclarativeAttributes <ServiceBusHostWorkerRoleAttribute>(ownerRole.GetType()); IRoleConfigurationSettingsExtension roleConfigExtension = ownerRole.Extensions.Find <IRoleConfigurationSettingsExtension>(); if (serviceHostAttributes != null && serviceHostAttributes.Count > 0 && roleConfigExtension != null) { ServiceBusEndpointInfo endpointInfo = null; ServiceBusListenerRegistration listenerInfo = null; foreach (ServiceBusHostWorkerRoleAttribute serviceHostAttr in serviceHostAttributes) { endpointInfo = roleConfigExtension.GetServiceBusEndpoint(serviceHostAttr.ServiceBusEndpoint); if (endpointInfo != null) { listenerInfo = new ServiceBusListenerRegistration() { ServiceType = serviceHostAttr.ServiceType, EndpointInfo = endpointInfo, AutoStart = serviceHostAttr.AutoStart }; // All services that are enabled for auto-start will have their service hosts pre-initialized but not as yet openned. if (listenerInfo.AutoStart) { TraceManager.WorkerRoleComponent.TraceInfo(TraceLogMessages.AboutToCreateServiceHost, listenerInfo.ServiceType.FullName, endpointInfo.Name, endpointInfo.ServiceNamespace, endpointInfo.ServicePath, endpointInfo.EndpointType); listenerInfo.ServiceHost = new ReliableServiceBusHost <object>(ServiceBusHostFactory.CreateServiceBusHost(endpointInfo, listenerInfo.ServiceType), roleConfigExtension.CommunicationRetryPolicy); } this.serviceEndpoints.Add(endpointInfo, listenerInfo); } else { throw new CloudApplicationException(String.Format(CultureInfo.CurrentCulture, ExceptionMessages.SpecifiedServiceBusEndpointNotFound, serviceHostAttr.ServiceBusEndpoint, ServiceBusConfigurationSettings.SectionName)); } } } } TraceManager.WorkerRoleComponent.TraceEndScope(TraceLogMessages.ScopeCreateServiceHosts, startScopeCreateServiceHosts, callToken); TraceManager.WorkerRoleComponent.TraceOut(callToken); }
/// <summary> /// Notifies this extension component that it has been registered in the owner's collection of extensions. /// </summary> /// <param name="owner">The extensible owner object that aggregates this extension.</param> public void Attach(IExtensibleCloudServiceComponent owner) { var callToken = TraceManager.WorkerRoleComponent.TraceIn(this.queueLocation.StorageAccount, this.queueLocation.QueueName); try { owner.Extensions.Demand <ICloudStorageProviderExtension>(); if (!this.queueLocation.IsDiscoverable) { var queueLocationResolvers = owner.Extensions.FindAll <ICloudQueueLocationResolverExtension>(); foreach (ICloudQueueLocationResolverExtension locationResolver in queueLocationResolvers) { this.queueLocation = locationResolver.GetQueueLocation(this.queueLocation.QueueName); if (this.queueLocation.IsDiscoverable) { break; } } } if (this.queueLocation.IsDiscoverable) { ICloudStorageProviderExtension storageProvider = owner.Extensions.Find <ICloudStorageProviderExtension>(); this.queueStorage = storageProvider.GetQueueStorage(this.queueLocation.StorageAccount); // Ensure that the queue is available, create a new queue if one doesn't exist. this.queueStorage.CreateQueue(this.queueLocation.QueueName); } else { throw new CloudApplicationException(String.Format(CultureInfo.CurrentCulture, ExceptionMessages.CloudQueueNotDiscoverable, this.queueLocation.QueueName)); } } finally { TraceManager.WorkerRoleComponent.TraceOut(callToken); } }
/// <summary> /// Notifies this extension component that it has been unregistered from the owner's collection of extensions. /// </summary> /// <param name="owner">The extensible owner object that aggregates this extension.</param> public void Detach(IExtensibleCloudServiceComponent owner) { if (this.defaultBlobStorage != null) { lock (this.syncRoot) { if (this.defaultBlobStorage != null) { this.defaultBlobStorage.Dispose(); this.defaultBlobStorage = null; } } } if (this.defaultQueueStorage != null) { lock (this.syncRoot) { if (this.defaultQueueStorage != null) { this.defaultQueueStorage.Dispose(); this.defaultQueueStorage = null; } } } if (this.defaultTableStorage != null) { lock (this.syncRoot) { if (this.defaultTableStorage != null) { this.defaultTableStorage.Dispose(); this.defaultTableStorage = null; } } } }
/// <summary> /// Notifies this extension component that it has been registered in the owner's collection of extensions. /// </summary> /// <param name="owner">The extensible owner object that aggregates this extension.</param> public void Attach(IExtensibleCloudServiceComponent owner) { this.workerRole = owner; }
/// <summary> /// Notifies this extension component that it has been unregistered from the owner's collection of extensions. /// </summary> /// <param name="owner">The extensible owner object that aggregates this extension.</param> public void Detach(IExtensibleCloudServiceComponent owner) { DisposeServiceHosts(); }
/// <summary> /// Notifies this extension component that it has been registered in the owner's collection of extensions. /// </summary> /// <param name="owner">The extensible owner object that aggregates this extension.</param> public void Attach(IExtensibleCloudServiceComponent owner) { this.workerRole = owner; ConfigureServiceHostWorkerRole(this.workerRole); }
/// <summary> /// Notifies this extension component that it has been registered in the owner's collection of extensions. /// </summary> /// <param name="owner">The extensible owner object that aggregates this extension.</param> public void Attach(IExtensibleCloudServiceComponent owner) { owner.Extensions.Demand <IRoleConfigurationSettingsExtension>(); IRoleConfigurationSettingsExtension roleConfigExtension = owner.Extensions.Find <IRoleConfigurationSettingsExtension>(); this.serviceBusEndpoint = roleConfigExtension.GetServiceBusEndpoint(WellKnownEndpointName.InterRoleCommunication); this.retryPolicy = roleConfigExtension.CommunicationRetryPolicy; if (this.serviceBusEndpoint != null) { // Configure Service Bus credentials and entity URI. var credentials = TransportClientCredentialBase.CreateSharedSecretCredential(this.serviceBusEndpoint.IssuerName, this.serviceBusEndpoint.IssuerSecret); var address = ServiceBusEnvironment.CreateServiceUri(WellKnownProtocolScheme.ServiceBus, this.serviceBusEndpoint.ServiceNamespace, String.Empty); // Configure Service Bus messaging factory and namespace client which is required for subscription management. this.messagingFactory = MessagingFactory.Create(address, credentials); this.managementClient = new ServiceBusNamespaceClient(address, credentials); ConfigureTopicClient(); ConfigureSubscriptionClient(this.ircSubscription = ConfigureSubscription(String.Concat(SubscriptionNamePrefix, this.senderInstanceID))); // Configure event receive action. this.receiveAction = (() => { BrokeredMessage msg = null; this.retryPolicy.ExecuteAction(() => { // Make sure we are not told to stop receiving while we are retrying. if (!cts.IsCancellationRequested) { if (EventReceiver.TryReceive(Settings.EventWaitTimeout, out msg)) { try { // Make sure we are not told to stop receiving while we were waiting for a new message. if (!cts.IsCancellationRequested) { // Extract the event data from brokered message. InterRoleCommunicationEvent e = msg.GetBody <InterRoleCommunicationEvent>(); // Notify all registered subscribers. NotifySubscribers(e); // Mark brokered message as complete. msg.Complete(this.retryPolicy); } else { msg.Defer(this.retryPolicy); } } catch (Exception ex) { // Abandons a brokered message and unlocks the message. msg.Abandon(this.retryPolicy); // Log an error. TraceManager.ServiceComponent.TraceError(ex); } } } }); }); // Configure event receive complete action. this.endReceive = ((ar) => { this.receiveAction.EndInvoke(ar); if (!cts.IsCancellationRequested) { this.receiveHandle = this.receiveAction.BeginInvoke(this.endReceive, null); } }); // Configure event send action. this.sendAction = ((e) => { this.retryPolicy.ExecuteAction(() => { EventSender.Send(e); }); }); // Configure event send complete action. this.endSend = ((ar) => { sendAction.EndInvoke(ar); }); } else { throw new CloudApplicationException(String.Format(CultureInfo.CurrentCulture, ExceptionMessages.SpecifiedServiceBusEndpointNotFound, WellKnownEndpointName.InterRoleCommunication, ServiceBusConfigurationSettings.SectionName)); } }
/// <summary> /// Notifies this extension component that it has been registered in the owner's collection of extensions. /// </summary> /// <param name="owner">The extensible owner object that aggregates this extension.</param> public void Attach(IExtensibleCloudServiceComponent owner) { this.configSettingsExtension = owner.Extensions.Find <IWorkItemProcessorConfigurationExtension>(); }
/// <summary> /// Notifies this extension component that it has been registered in the owner's collection of extensions. /// </summary> /// <param name="owner">The extensible owner object that aggregates this extension.</param> public void Attach(IExtensibleCloudServiceComponent owner) { owner.EnsureExists <RulesEngineServiceClientExtension>(); this.owner = owner; }
/// <summary> /// Notifies this extension component that it has been registered in the owner's collection of extensions. /// </summary> /// <param name="owner">The extensible owner object that aggregates this extension.</param> public void Attach(IExtensibleCloudServiceComponent owner) { this.discoveryClientRegistration = ServiceEndpointConfiguration.RegisterDiscoveryClient(this); }
/// <summary> /// Notifies this extension component that it has been registered in the owner's collection of extensions. /// </summary> /// <param name="owner">The extensible owner object that aggregates this extension.</param> public void Attach(IExtensibleCloudServiceComponent owner) { owner.Extensions.Demand <ICloudStorageProviderExtension>(); this.cloudStorageProvider = owner.Extensions.Find <ICloudStorageProviderExtension>(); }
/// <summary> /// Notifies this extension component that it has been registered in the owner's collection of extensions. /// </summary> /// <param name="owner">The extensible owner object that aggregates this extension.</param> public void Attach(IExtensibleCloudServiceComponent owner) { IRoleConfigurationSettingsExtension roleConfigExtension = owner.Extensions.Find <IRoleConfigurationSettingsExtension>(); if (roleConfigExtension != null && CloudEnvironment.IsAvailable) { ApplicationDiagnosticSettings diagnosticSettings = roleConfigExtension.GetSection <ApplicationDiagnosticSettings>(ApplicationDiagnosticSettings.SectionName); StorageAccountConfigurationSettings storageSettings = roleConfigExtension.GetSection <StorageAccountConfigurationSettings>(StorageAccountConfigurationSettings.SectionName); if (diagnosticSettings != null) { if (diagnosticSettings.DiagnosticEnabled) { DiagnosticMonitorConfiguration diagnosticConfig = DiagnosticMonitor.GetDefaultInitialConfiguration(); // Configure the scheduled transfer period for all logs. diagnosticConfig.DiagnosticInfrastructureLogs.ScheduledTransferPeriod = diagnosticSettings.DiagnosticLogsTransferPeriod.Coalesce(diagnosticSettings.DefaultTransferPeriod); diagnosticConfig.Directories.ScheduledTransferPeriod = diagnosticSettings.FileLogsTransferPeriod.Coalesce(diagnosticSettings.DefaultTransferPeriod); diagnosticConfig.Logs.ScheduledTransferPeriod = diagnosticSettings.TraceLogsTransferPeriod.Coalesce(diagnosticSettings.DefaultTransferPeriod); diagnosticConfig.PerformanceCounters.ScheduledTransferPeriod = diagnosticSettings.PerformanceCountersTransferPeriod.Coalesce(diagnosticSettings.DefaultTransferPeriod); diagnosticConfig.WindowsEventLog.ScheduledTransferPeriod = diagnosticSettings.EventLogsTransferPeriod.Coalesce(diagnosticSettings.DefaultTransferPeriod); // Configure the logs levels for scheduled transfers. diagnosticConfig.DiagnosticInfrastructureLogs.ScheduledTransferLogLevelFilter = FromTraceSourceLevel(diagnosticSettings.DiagnosticLogsTransferFilter); diagnosticConfig.Logs.ScheduledTransferLogLevelFilter = FromTraceSourceLevel(diagnosticSettings.TraceLogsTransferFilter); diagnosticConfig.WindowsEventLog.ScheduledTransferLogLevelFilter = FromTraceSourceLevel(diagnosticSettings.EventLogsTransferFilter); // Configure the Windows Event Log data sources. foreach (string logName in diagnosticSettings.EventLogDataSources.AllKeys) { diagnosticConfig.WindowsEventLog.DataSources.Add(logName); } // Configure the data sources for file-based logs. foreach (string containerName in diagnosticSettings.FileLogDirectories.AllKeys) { diagnosticConfig.Directories.DataSources.Add(new DirectoryConfiguration() { Container = containerName, Path = diagnosticSettings.FileLogDirectories[containerName].Value }); } // Configure the data sources for performance counter data foreach (string counterName in diagnosticSettings.PerformanceCountersDataSources.AllKeys) { diagnosticConfig.PerformanceCounters.DataSources.Add(new PerformanceCounterConfiguration() { CounterSpecifier = counterName, SampleRate = TimeSpan.Parse(diagnosticSettings.PerformanceCountersDataSources[counterName].Value) }); } // Configure crash dumps collection. if (diagnosticSettings.CrashDumpCollectionEnabled) { CrashDumps.EnableCollection(true); } // Look up for the storage account definition. StorageAccountInfo storageAccountInfo = storageSettings.Accounts.Get(diagnosticSettings.DiagnosticStorageAccount); if (storageAccountInfo != null) { CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentialsAccountAndKey(storageAccountInfo.AccountName, storageAccountInfo.AccountKey), true); RetryPolicy retryPolicy = roleConfigExtension.StorageRetryPolicy; // Start the Azure Diagnostic Monitor using a retryable scope. this.diagnosticMonitor = retryPolicy.ExecuteAction <DiagnosticMonitor>(() => { return(DiagnosticMonitor.Start(storageAccount, diagnosticConfig)); }); } } else { // Do not proceed any further since diagnostic is not enabled in the application configuration. return; } } } if (null == this.diagnosticMonitor) { // Configuration extension is not available by some reasons, let try and see if DiagnosticsConnectionString property is set in the configuration. string diagConnectionString = CloudEnvironment.GetConfigurationSettingValue(Resources.DiagnosticsConnectionStringSettingName); // If DiagnosticsConnectionString is defined, start a Diagnostic Monitor using the storage account configuration specified in the setting. if (!String.IsNullOrEmpty(diagConnectionString)) { this.diagnosticMonitor = DiagnosticMonitor.Start(diagConnectionString, GetDiagnosticMonitorDefaultConfiguration()); } } }
/// <summary> /// Notifies this extension component that it has been unregistered from the owner's collection of extensions. /// </summary> /// <param name="owner">The extensible owner object that aggregates this extension.</param> public void Detach(IExtensibleCloudServiceComponent owner) { this.owner = null; }
/// <summary> /// Notifies this extension component that it has been unregistered from the owner's collection of extensions. /// </summary> /// <param name="owner">The extensible owner object that aggregates this extension.</param> public void Detach(IExtensibleCloudServiceComponent owner) { }
/// <summary> /// Notifies this extension component that it has been registered in the owner's collection of extensions. /// </summary> /// <param name="owner">The extensible owner object that aggregates this extension.</param> public void Attach(IExtensibleCloudServiceComponent owner) { this.owner = owner; this.owner.Extensions.Demand <IXslTransformMetadataProviderExtension>(); this.metadataProvider = owner.Extensions.Find <IXslTransformMetadataProviderExtension>(); }