ExternalDataExchangeService.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WF / Activities / LocalService / ExternalDataExchangeService.cs / 1305376 / ExternalDataExchangeService.cs

                            //------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------

using System; 
using System.Diagnostics;
using System.Collections; 
using System.Collections.ObjectModel; 
using System.Collections.Generic;
using System.Collections.Specialized; 
using System.Reflection;
using System.Workflow.ComponentModel;
using System.Workflow.Runtime;
using System.Workflow.Runtime.Configuration; 
using System.Workflow.Runtime.Hosting;
using System.Runtime.Serialization; 
using System.Globalization; 
using System.Threading;
using System.Runtime.Serialization.Formatters.Binary; 
using System.Configuration;

namespace System.Workflow.Activities
{ 
    internal interface IDeliverMessage
    { 
        object[] PrepareEventArgsArray(object sender, ExternalDataEventArgs eventArgs,out object workItem, out IPendingWork workHandler); 
        void DeliverMessage(ExternalDataEventArgs eventArgs, IComparable queueName, object message, object workItem, IPendingWork workHandler);
    } 

    public class ExternalDataExchangeServiceSection : ConfigurationSection
    {
        private const string _services = "Services"; 

        ///  The providers to be instantiated by the service container.  
        [ConfigurationProperty(_services, DefaultValue = null)] 
        public WorkflowRuntimeServiceElementCollection Services
        { 
            get
            {
                return (WorkflowRuntimeServiceElementCollection)base[_services];
            } 
        }
    } 
 
    public class ExternalDataExchangeService : WorkflowRuntimeService
    { 
        Dictionary eventHandlers = null;
        object handlersLock = new object();
        private const string configurationSectionAttributeName = "ConfigurationSection";
        ExternalDataExchangeServiceSection settings = null; 
        IDeliverMessage enqueueMessageWrapper = null;
        List services; 
        object servicesLock = new object(); 

        public ExternalDataExchangeService() 
        {
            this.eventHandlers = new Dictionary();
            this.services = new List();
            this.enqueueMessageWrapper = new EnqueueMessageWrapper(this); 
        }
 
        public ExternalDataExchangeService(string configSectionName) 
            : this()
        { 
            if (configSectionName == null)
                throw new ArgumentNullException("configSectionName");

            settings = ConfigurationManager.GetSection(configSectionName) as ExternalDataExchangeServiceSection; 
            if (settings == null)
                throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, 
                    SR.GetString(SR.Error_ConfigurationSectionNotFound), configSectionName)); 
        }
 
        public ExternalDataExchangeService(NameValueCollection parameters)
            : this()
        {
            if (parameters == null) 
                throw new ArgumentNullException("parameters");
            string configurationSectionName = null; 
 
            foreach (string key in parameters.Keys)
            { 
                if (key.Equals(configurationSectionAttributeName, StringComparison.OrdinalIgnoreCase))
                {
                    configurationSectionName = parameters[key];
                } 
                else
                { 
                    throw new ArgumentException( 
                        String.Format(Thread.CurrentThread.CurrentCulture, SR.GetString(SR.Error_UnknownConfigurationParameter), key), "parameters");
                } 
            }
            if (configurationSectionName != null)
            {
                settings = ConfigurationManager.GetSection(configurationSectionName) as ExternalDataExchangeServiceSection; 
                if (settings == null)
                    throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, 
                        SR.GetString(SR.Error_ConfigurationSectionNotFound), configurationSectionName)); 
            }
 
        }

        public ExternalDataExchangeService(ExternalDataExchangeServiceSection settings)
            : this() 
        {
            if (settings == null) 
                throw new ArgumentNullException("settings"); 

            this.settings = settings; 
        }

        internal ReadOnlyCollection GetAllServices()
        { 
            ReadOnlyCollection collection;
            lock (this.servicesLock) 
            { 
                collection = this.services.AsReadOnly();
            } 

            return collection;
        }
 
        protected override void Start()
        { 
            if (settings != null) 
            {
                foreach (WorkflowRuntimeServiceElement service in settings.Services) 
                {
                    AddService(ServiceFromSettings(service));
                }
            } 

            if (this.Runtime != null) 
            { 
                base.Start();
            } 
        }

        internal void SetEnqueueMessageWrapper(IDeliverMessage wrapper)
        { 
            this.enqueueMessageWrapper = wrapper;
            foreach (WorkflowMessageEventHandler eventHandler in this.eventHandlers.Values) 
            { 
                eventHandler.EnqueueWrapper = wrapper;
            } 
        }

        // Todo: This is duplicate of code in WorkflowRuntime
        internal object ServiceFromSettings(WorkflowRuntimeServiceElement serviceSettings) 
        {
            object service = null; 
 
            Type t = Type.GetType(serviceSettings.Type, true);
 
            ConstructorInfo serviceProviderAndSettingsConstructor = null;
            ConstructorInfo serviceProviderConstructor = null;
            ConstructorInfo settingsConstructor = null;
 
            foreach (ConstructorInfo ci in t.GetConstructors())
            { 
                ParameterInfo[] pi = ci.GetParameters(); 
                if (pi.Length == 1)
                { 
                    if (typeof(IServiceProvider).IsAssignableFrom(pi[0].ParameterType))
                    {
                        serviceProviderConstructor = ci;
                    } 
                    else if (typeof(NameValueCollection).IsAssignableFrom(pi[0].ParameterType))
                    { 
                        settingsConstructor = ci; 
                    }
                } 
                else if (pi.Length == 2)
                {
                    if (typeof(IServiceProvider).IsAssignableFrom(pi[0].ParameterType)
                        && typeof(NameValueCollection).IsAssignableFrom(pi[1].ParameterType)) 
                    {
                        serviceProviderAndSettingsConstructor = ci; 
                        break; 
                    }
                } 
            }

            if (serviceProviderAndSettingsConstructor != null)
            { 
                service = serviceProviderAndSettingsConstructor.Invoke(
                    new object[] { Runtime, serviceSettings.Parameters }); 
            } 
            else if (serviceProviderConstructor != null)
            { 
                service = serviceProviderConstructor.Invoke(new object[] { Runtime });
            }
            else if (settingsConstructor != null)
            { 
                service = settingsConstructor.Invoke(new object[] { serviceSettings.Parameters });
            } 
            else 
            {
                service = Activator.CreateInstance(t); 
            }
            return service;
        }
 
        public virtual void AddService(object service)
        { 
            if (service == null) 
                throw new ArgumentNullException("service");
 
            InterceptService(service, true);
            if (this.Runtime != null)
            {
                this.Runtime.AddService(service); 
            }
            else 
            { 
                lock (this.servicesLock)
                { 
                    this.services.Add(service);
                }
            }
        } 

        public virtual void RemoveService(object service) 
        { 
            if (service == null)
                throw new ArgumentNullException("service"); 

            InterceptService(service, false);
            if (this.Runtime != null)
            { 
                this.Runtime.RemoveService(service);
            } 
            else 
            {
                lock (this.servicesLock) 
                {
                    this.services.Remove(service);
                }
            } 
        }
 
        public virtual object GetService(Type serviceType) 
        {
            if (serviceType == null) 
                throw new ArgumentNullException("serviceType");

            if (this.Runtime != null)
            { 
                return this.Runtime.GetService(serviceType); ;
            } 
            else 
            {
                lock (this.servicesLock) 
                {
                    foreach (object service in this.services)
                    {
                        if (serviceType.IsAssignableFrom(service.GetType())) 
                        {
                            return service; 
                        } 
                    }
 
                    return null;
                }
            }
        } 

        internal void InterceptService(object service, bool add) 
        { 
            bool isDataExchangeService = false;
            Type[] interfaceTypes = service.GetType().GetInterfaces(); 
            foreach (Type type in interfaceTypes)
            {
                object[] attributes = type.GetCustomAttributes(typeof(ExternalDataExchangeAttribute), false);
                if (attributes.Length == 0) 
                    continue;
 
                if (this.Runtime != null && this.Runtime.GetService(type) != null && add) 
                    throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, SR.GetString(SR.Error_ExternalDataExchangeServiceExists), type));
 
                isDataExchangeService = true;
                EventInfo[] events = type.GetEvents();
                if (events == null)
                    continue; 

                foreach (EventInfo e in events) 
                { 
                    WorkflowMessageEventHandler handler = null;
                    int hash = type.GetHashCode() ^ e.Name.GetHashCode(); 
                    lock (handlersLock)
                    {
                        if (!this.eventHandlers.ContainsKey(hash))
                        { 
                            handler = new WorkflowMessageEventHandler(type, e, this.enqueueMessageWrapper);
                            this.eventHandlers.Add(hash, handler); 
                        } 
                        else
                        { 
                            handler = this.eventHandlers[hash];
                        }
                    }
                    AddRemove(service, handler.Delegate, add, e.Name); 
                }
            } 
            if (!isDataExchangeService) 
                throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, SR.GetString(SR.Error_ServiceMissingExternalDataExchangeInterface)));
        } 

        private void AddRemove(object addedservice, Delegate delg, bool add, string eventName)
        {
            try 
            {
                string eventAction; 
                if (add) 
                    eventAction = "add_" + eventName;
                else 
                    eventAction = "remove_" + eventName;

                Type serviceType = addedservice.GetType();
                if (delg != null) 
                {
                    // add or remove interception handler 
                    object[] del = { delg }; 
                    serviceType.InvokeMember(eventAction, BindingFlags.InvokeMethod, null, addedservice, del, null);
                } 
            }
            catch (Exception e)
            {
                if (IsIrrecoverableException(e)) 
                {
                    throw; 
                } 
                // cannot intercept this event
            } 
        }

        internal static bool IsIrrecoverableException(Exception e)
        { 
            return ((e is OutOfMemoryException) ||
                    (e is StackOverflowException) || 
                    (e is ThreadInterruptedException) || 
                    (e is ThreadAbortException));
        } 

        class EnqueueMessageWrapper : IDeliverMessage
        {
            ExternalDataExchangeService eds; 

            public EnqueueMessageWrapper(ExternalDataExchangeService eds) 
            { 
                this.eds = eds;
            } 

            public object[] PrepareEventArgsArray(object sender, ExternalDataEventArgs eventArgs, out object workItem, out IPendingWork workHandler)
            {
                // remove the batch items from the event args, only the runtime needs this data 
                // and it is not necessarily serializable.
                workItem = eventArgs.WorkItem; 
                eventArgs.WorkItem = null; 
                workHandler = eventArgs.WorkHandler;
                eventArgs.WorkHandler = null; 

                return new object[] { sender, eventArgs };
            }
            public void DeliverMessage(ExternalDataEventArgs eventArgs, IComparable queueName, object message, object workItem, IPendingWork workHandler) 
            {
                WorkflowInstance workflowInstance = this.eds.Runtime.GetWorkflow(eventArgs.InstanceId); 
                if (eventArgs.WaitForIdle) 
                {
                    workflowInstance.EnqueueItemOnIdle(queueName, message, workHandler, workItem); 
                }
                else
                {
                    workflowInstance.EnqueueItem(queueName, message, workHandler, workItem); 
                }
            } 
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK