CorrelationResolver.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

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

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

#region Using directives 

using System; 
using System.Diagnostics; 
using System.Collections.Generic;
using System.Text; 
using System.Reflection;
using System.Runtime.Serialization;
using System.Workflow.ComponentModel;
using System.Runtime.Remoting; 
using System.Runtime.Remoting.Messaging;
using System.Workflow.Runtime; 
using System.Xml; 

#endregion 

namespace System.Workflow.Activities
{
    internal static class CorrelationResolver 
    {
        static Dictionary cachedTypeResolver = new Dictionary(); 
        static object mutex = new object(); 

        internal static bool IsInitializingMember(Type interfaceType, string memberName, object[] methodArgs) 
        {
            if (interfaceType == null)
                throw new ArgumentNullException("interfaceType");
            if (memberName == null) 
                throw new ArgumentNullException("memberName");
            if (memberName.Length == 0) 
                throw new ArgumentException(SR.GetString(SR.Error_EventNameMissing)); 

            ICorrelationProvider correlationProvider = CorrelationResolver.GetCorrelationProvider(interfaceType); 
            return correlationProvider.IsInitializingMember(interfaceType, memberName, methodArgs);
        }

        internal static ICollection ResolveCorrelationValues(Type interfaceType, string eventName, object[] eventArgs, bool provideInitializerTokens) 
        {
            if (interfaceType == null) 
                throw new ArgumentNullException("interfaceType"); 
            if (eventName == null)
                throw new ArgumentNullException("eventName"); 
            if (eventName.Length == 0)
                throw new ArgumentException(SR.GetString(SR.Error_EventNameMissing));

            ICorrelationProvider correlationProvider = CorrelationResolver.GetCorrelationProvider(interfaceType); 
            return correlationProvider.ResolveCorrelationPropertyValues(interfaceType, eventName, eventArgs, provideInitializerTokens);
        } 
 
        internal static ICorrelationProvider GetCorrelationProvider(Type interfaceType)
        { 
            CorrelationMethodResolver resolver = GetResolver(interfaceType);
            return resolver.CorrelationProvider;
        }
 
        private static CorrelationMethodResolver GetResolver(Type interfaceType)
        { 
            CorrelationMethodResolver resolver = null; 
            cachedTypeResolver.TryGetValue(interfaceType, out resolver);
            if (resolver == null) 
            {
                lock (mutex)
                {
                    cachedTypeResolver.TryGetValue(interfaceType, out resolver); 
                    if (resolver == null)
                    { 
                        resolver = new CorrelationMethodResolver(interfaceType); 
                        cachedTypeResolver.Add(interfaceType, resolver);
                    } 
                }
            }
            return resolver;
        } 
    }
 
    internal sealed class CorrelationMethodResolver 
    {
        Type interfaceType; 

        // a correlation provider for each interface type
        ICorrelationProvider correlationProvider;
        object corrProviderSync = new object(); 

        internal CorrelationMethodResolver(Type interfaceType) 
        { 
            this.interfaceType = interfaceType;
        } 

        internal ICorrelationProvider CorrelationProvider
        {
            get 
            {
                if (this.correlationProvider == null) 
                { 
                    lock (this.corrProviderSync)
                    { 
                        if (this.correlationProvider == null)
                        {
                            ICorrelationProvider provider = null;
                            object[] corrProviderAttribs = this.interfaceType.GetCustomAttributes(typeof(CorrelationProviderAttribute), true); 
                            if (corrProviderAttribs.Length == 0)
                            { 
                                corrProviderAttribs = this.interfaceType.GetCustomAttributes(typeof(ExternalDataExchangeAttribute), true); 
                                object[] corrParameterAttribs = this.interfaceType.GetCustomAttributes(typeof(CorrelationParameterAttribute), true);
                                if (corrProviderAttribs.Length != 0 && corrParameterAttribs.Length != 0) 
                                {
                                    // no provider specified but it is a data exchange correlation service
                                    // hence use our default correlation
                                    provider = new DefaultCorrelationProvider(this.interfaceType); 
                                }
                                else 
                                { 
                                    // opaque interface with no correlation
                                    provider = new NonCorrelatedProvider(); 
                                }
                            }
                            else
                            { 
                                CorrelationProviderAttribute cpattrib = corrProviderAttribs[0] as CorrelationProviderAttribute;
                                Type providerType = cpattrib.CorrelationProviderType; 
                                provider = Activator.CreateInstance(providerType) as ICorrelationProvider; 
                            }
 
                            System.Threading.Thread.MemoryBarrier();
                            this.correlationProvider = provider;
                        }
                    } 
                }
 
                return this.correlationProvider; 
            }
        } 
    }

    internal sealed class CorrelationPropertyValue
    { 
        string  name;
        string  locationPath; 
        int     signaturePosition; 

        internal CorrelationPropertyValue(string name, string locationPath, int signaturePosition) 
        {
            this.name = name;
            this.locationPath = locationPath;
            this.signaturePosition = signaturePosition; 
        }
 
        internal object GetValue(object[] args) 
        {
            if (args.Length <= this.signaturePosition) 
                throw new ArgumentOutOfRangeException("args");

            object arg = args[this.signaturePosition];
            if (arg == null) 
                return arg;
            Type type = arg.GetType(); 
            object val = arg; 
            if (this.locationPath.Length != 0)
            { 
                string[] split = locationPath.Split(new Char[] { '.' });
                for (int i = 1; i < split.Length; i++ )
                {
                    string s = split[i]; 
                    if (null == arg)
                        break; 
                    val = type.InvokeMember(s, BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetField | BindingFlags.GetProperty, null, arg, null, null); 

                    MemberInfo[] mInfos = type.GetMember(s, BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetField | BindingFlags.GetProperty); 

                    type = GetMemberType(mInfos[0]);
                    arg = val;
                } 
            }
            return val; 
        } 

        internal string Name 
        {
            get
            {
                return this.name; 
            }
        } 
 
        private Type GetMemberType(MemberInfo mInfo)
        { 
            Type type = null;
            switch (mInfo.MemberType)
            {
                case MemberTypes.Field: 
                    type = ((FieldInfo)mInfo).FieldType;
                    break; 
 
                case MemberTypes.Property:
                    type = ((PropertyInfo)mInfo).PropertyType; 
                    break;

                default:
                    Debug.Assert(false, "locationPath points to something other than a Field/Property"); 
                    return null;
            } 
 
            return type;
        } 
    }

    internal sealed class DefaultCorrelationProvider : ICorrelationProvider
    { 
        Type interfaceType;
 
        // map of method name to correlation properties 
        Dictionary cachedCorrelationProperties;
        object cachedCorrelationPropertiesSync = new object(); 

        // cached initializers
        // map operation to bool flag to indicate events
        Dictionary initializerCorrelationPropertys = null; 
        object initializerCorrelationPropertysSync = new object();
 
        internal DefaultCorrelationProvider(Type interfaceType) 
        {
            this.cachedCorrelationProperties = new Dictionary(); 
            this.interfaceType = interfaceType;
        }

        ICollection ICorrelationProvider.ResolveCorrelationPropertyValues(Type interfaceType, string methodName, object[] methodArgs, bool provideInitializerTokens) 
        {
            CorrelationPropertyValue[] correlationProperties = null; 
 
            if (methodArgs == null || provideInitializerTokens)
            { 
                return null; // no initializer specific token to return
            }

            this.cachedCorrelationProperties.TryGetValue(methodName, out correlationProperties); 
            if (correlationProperties == null)
            { 
                lock (this.cachedCorrelationPropertiesSync) 
                {
                    this.cachedCorrelationProperties.TryGetValue(methodName, out correlationProperties); 
                    if (correlationProperties == null)
                    {
                        correlationProperties = GetCorrelationProperties(interfaceType, methodName);
                        this.cachedCorrelationProperties.Add(methodName, correlationProperties); 
                    }
                } 
            } 

            List predicates = new List(); 
            for (int i = 0; i < correlationProperties.Length; i++)
            {
                predicates.Add(new CorrelationProperty(correlationProperties[i].Name,correlationProperties[i].GetValue(methodArgs)));
            } 

            return predicates; 
        } 

        private Dictionary InitializerCorrelationPropertys 
        {
            get
            {
                if (this.initializerCorrelationPropertys == null) 
                {
                    lock (this.initializerCorrelationPropertysSync) 
                    { 
                        if (this.initializerCorrelationPropertys == null)
                        { 
                            Dictionary members = new Dictionary();
                            // note this is separated out since we may need to distinguish between events & methods
                            foreach (EventInfo member in this.interfaceType.GetEvents())
                            { 
                                if ((member.GetCustomAttributes(typeof(CorrelationInitializerAttribute), true)).Length > 0)
                                { 
                                    members.Add(member.Name, true); 
                                }
                            } 
                            foreach (MethodInfo member in this.interfaceType.GetMethods())
                            {
                                if ((member.GetCustomAttributes(typeof(CorrelationInitializerAttribute), true)).Length > 0)
                                { 
                                    members.Add(member.Name, false);
                                } 
                            } 

                            this.initializerCorrelationPropertys = members; 
                        }
                    }
                }
                return this.initializerCorrelationPropertys; 
            }
        } 
 
 		bool ICorrelationProvider.IsInitializingMember(Type interfaceType, string memberName, object[] methodArgs)
        { 
			return InitializerCorrelationPropertys.ContainsKey(memberName);
        }

        private CorrelationPropertyValue[] GetCorrelationProperties(Type interfaceType, string methodName) 
        {
            CorrelationPropertyValue[] correlationProperties = null; 
 
            if (interfaceType.GetCustomAttributes(typeof(ExternalDataExchangeAttribute), true).Length == 0)
                throw new InvalidOperationException(SR.GetString(SR.Error_ExternalDataExchangeException,interfaceType.AssemblyQualifiedName)); 

            List correlationParamAttributes = new List();
            correlationParamAttributes.AddRange(GetCorrelationParameterAttributes(interfaceType));
 
            if (correlationParamAttributes.Count == 0)
                throw new InvalidOperationException(SR.GetString(SR.Error_CorrelationParameterException, interfaceType.AssemblyQualifiedName)); 
 
            correlationProperties = new CorrelationPropertyValue[correlationParamAttributes.Count];
 
            Dictionary corrAliases = null;
            MethodInfo methodInfo = null;

            GetMethodInfo(interfaceType, methodName, out methodInfo, out corrAliases); 

            if (methodInfo == null) 
            { 
                throw new MissingMethodException(interfaceType.AssemblyQualifiedName, methodName);
            } 

            ParameterInfo[] parameters = methodInfo.GetParameters();

            int i = 0; 
            foreach (CorrelationParameterAttribute paramAttribute in correlationParamAttributes)
            { 
                String location = paramAttribute.Name; 
                CorrelationAliasAttribute aliasAttribute = GetMatchingCorrelationAlias(paramAttribute, corrAliases, correlationParamAttributes.Count == 1);
 
                if (aliasAttribute != null)
                    location = aliasAttribute.Path;

                CorrelationPropertyValue value = GetCorrelationProperty(parameters, paramAttribute.Name, location); 
                if (value == null)
                    throw new InvalidOperationException(SR.GetString(SR.Error_CorrelationParameterException,interfaceType.AssemblyQualifiedName, paramAttribute.Name, methodName)); 
 
                correlationProperties[i++] = value;
            } 
            return correlationProperties;
        }

        private CorrelationAliasAttribute GetMatchingCorrelationAlias(CorrelationParameterAttribute paramAttribute, Dictionary correlationAliases, bool defaultParameter) 
        {
            CorrelationAliasAttribute corrAlias = null; 
 
            if (correlationAliases == null) return null;
 
            if (defaultParameter)
            {
                if (correlationAliases.TryGetValue("", out corrAlias))
                { 
                    return corrAlias;
                } 
            } 

            correlationAliases.TryGetValue(paramAttribute.Name, out corrAlias); 
            return corrAlias;
        }

        private CorrelationPropertyValue GetCorrelationProperty(ParameterInfo[] parameters, String propertyName, String location) 
        {
            string[] split = location.Split(new Char[] { '.' }); 
 
            if (split.Length == 1 && parameters.Length == 2)
            { 
                if (typeof(ExternalDataEventArgs).IsAssignableFrom(parameters[1].ParameterType))
                {
                    string aliasedLocation = "e." + location;
                    return GetCorrelationProperty(parameters, propertyName, "e", aliasedLocation); 
                }
 
            } 
            string parameterName = split[0];
 
            return GetCorrelationProperty(parameters, propertyName, parameterName, location);
        }

        private void GetMethodInfo(Type interfaceType, string methodName, out MethodInfo methodInfo, out Dictionary correlationAliases) 
        {
            correlationAliases = new Dictionary(); 
            Object[] customAttrs = null; 
            methodInfo = null;
            // check events 
            BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
            EventInfo eventInfo = interfaceType.GetEvent(methodName, bindingFlags);
            if (eventInfo != null)
            { 
                customAttrs = eventInfo.GetCustomAttributes(typeof(CorrelationAliasAttribute), true);
                if (customAttrs == null || customAttrs.Length == 0) 
                { 
                      customAttrs = eventInfo.EventHandlerType.GetCustomAttributes(typeof(CorrelationAliasAttribute), true);
                } 
                MethodInfo[] methInfo = eventInfo.EventHandlerType.GetMethods();
                methodInfo = methInfo[0];
            }
            else 
            {
                // check methods 
                methodInfo = interfaceType.GetMethod(methodName, bindingFlags); 
                if (methodInfo == null)
                { 
                    throw new MissingMethodException(interfaceType.AssemblyQualifiedName, methodName);
                }
                customAttrs = methodInfo.GetCustomAttributes(typeof(CorrelationAliasAttribute), true);
            } 

            foreach (CorrelationAliasAttribute aliasAttribute in customAttrs) 
            { 
                if (customAttrs.Length > 1)
                { 
                    Debug.Assert(aliasAttribute.Name != null);
                    if (aliasAttribute.Name == null)
                        throw new ArgumentNullException("ParameterName");
                } 
                correlationAliases.Add(aliasAttribute.Name == null ? "" : aliasAttribute.Name, aliasAttribute);
            } 
        } 

        private CorrelationPropertyValue GetCorrelationProperty(ParameterInfo[] parameters, string propertyName, string parameterName, string location) 
        {
            for (int j = 0; parameters != null && j < parameters.Length; j++)
            {
                ParameterInfo param = parameters[j]; 
                if (param.Name == parameterName)
                { 
                    // parameter match 
                    return new CorrelationPropertyValue(propertyName, location, param.Position);
                } 
            }

            return null;
        } 

        private object[] GetCorrelationParameterAttributes(Type type) 
        { 
            return type.GetCustomAttributes(typeof(CorrelationParameterAttribute), true);
        } 
    }

    internal sealed class NonCorrelatedProvider : ICorrelationProvider
    { 
        internal NonCorrelatedProvider()
        { 
        } 

        ICollection ICorrelationProvider.ResolveCorrelationPropertyValues(Type interfaceType, string methodName, object[] methodArgs, bool provideInitializerTokens) 
        {
            // non correlated
            // no values to return
            return null; 
        }
 
        bool ICorrelationProvider.IsInitializingMember(Type interfaceType, string memberName, object[] methodArgs) 
        {
            return true; 
        }
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------

#region Using directives 

using System; 
using System.Diagnostics; 
using System.Collections.Generic;
using System.Text; 
using System.Reflection;
using System.Runtime.Serialization;
using System.Workflow.ComponentModel;
using System.Runtime.Remoting; 
using System.Runtime.Remoting.Messaging;
using System.Workflow.Runtime; 
using System.Xml; 

#endregion 

namespace System.Workflow.Activities
{
    internal static class CorrelationResolver 
    {
        static Dictionary cachedTypeResolver = new Dictionary(); 
        static object mutex = new object(); 

        internal static bool IsInitializingMember(Type interfaceType, string memberName, object[] methodArgs) 
        {
            if (interfaceType == null)
                throw new ArgumentNullException("interfaceType");
            if (memberName == null) 
                throw new ArgumentNullException("memberName");
            if (memberName.Length == 0) 
                throw new ArgumentException(SR.GetString(SR.Error_EventNameMissing)); 

            ICorrelationProvider correlationProvider = CorrelationResolver.GetCorrelationProvider(interfaceType); 
            return correlationProvider.IsInitializingMember(interfaceType, memberName, methodArgs);
        }

        internal static ICollection ResolveCorrelationValues(Type interfaceType, string eventName, object[] eventArgs, bool provideInitializerTokens) 
        {
            if (interfaceType == null) 
                throw new ArgumentNullException("interfaceType"); 
            if (eventName == null)
                throw new ArgumentNullException("eventName"); 
            if (eventName.Length == 0)
                throw new ArgumentException(SR.GetString(SR.Error_EventNameMissing));

            ICorrelationProvider correlationProvider = CorrelationResolver.GetCorrelationProvider(interfaceType); 
            return correlationProvider.ResolveCorrelationPropertyValues(interfaceType, eventName, eventArgs, provideInitializerTokens);
        } 
 
        internal static ICorrelationProvider GetCorrelationProvider(Type interfaceType)
        { 
            CorrelationMethodResolver resolver = GetResolver(interfaceType);
            return resolver.CorrelationProvider;
        }
 
        private static CorrelationMethodResolver GetResolver(Type interfaceType)
        { 
            CorrelationMethodResolver resolver = null; 
            cachedTypeResolver.TryGetValue(interfaceType, out resolver);
            if (resolver == null) 
            {
                lock (mutex)
                {
                    cachedTypeResolver.TryGetValue(interfaceType, out resolver); 
                    if (resolver == null)
                    { 
                        resolver = new CorrelationMethodResolver(interfaceType); 
                        cachedTypeResolver.Add(interfaceType, resolver);
                    } 
                }
            }
            return resolver;
        } 
    }
 
    internal sealed class CorrelationMethodResolver 
    {
        Type interfaceType; 

        // a correlation provider for each interface type
        ICorrelationProvider correlationProvider;
        object corrProviderSync = new object(); 

        internal CorrelationMethodResolver(Type interfaceType) 
        { 
            this.interfaceType = interfaceType;
        } 

        internal ICorrelationProvider CorrelationProvider
        {
            get 
            {
                if (this.correlationProvider == null) 
                { 
                    lock (this.corrProviderSync)
                    { 
                        if (this.correlationProvider == null)
                        {
                            ICorrelationProvider provider = null;
                            object[] corrProviderAttribs = this.interfaceType.GetCustomAttributes(typeof(CorrelationProviderAttribute), true); 
                            if (corrProviderAttribs.Length == 0)
                            { 
                                corrProviderAttribs = this.interfaceType.GetCustomAttributes(typeof(ExternalDataExchangeAttribute), true); 
                                object[] corrParameterAttribs = this.interfaceType.GetCustomAttributes(typeof(CorrelationParameterAttribute), true);
                                if (corrProviderAttribs.Length != 0 && corrParameterAttribs.Length != 0) 
                                {
                                    // no provider specified but it is a data exchange correlation service
                                    // hence use our default correlation
                                    provider = new DefaultCorrelationProvider(this.interfaceType); 
                                }
                                else 
                                { 
                                    // opaque interface with no correlation
                                    provider = new NonCorrelatedProvider(); 
                                }
                            }
                            else
                            { 
                                CorrelationProviderAttribute cpattrib = corrProviderAttribs[0] as CorrelationProviderAttribute;
                                Type providerType = cpattrib.CorrelationProviderType; 
                                provider = Activator.CreateInstance(providerType) as ICorrelationProvider; 
                            }
 
                            System.Threading.Thread.MemoryBarrier();
                            this.correlationProvider = provider;
                        }
                    } 
                }
 
                return this.correlationProvider; 
            }
        } 
    }

    internal sealed class CorrelationPropertyValue
    { 
        string  name;
        string  locationPath; 
        int     signaturePosition; 

        internal CorrelationPropertyValue(string name, string locationPath, int signaturePosition) 
        {
            this.name = name;
            this.locationPath = locationPath;
            this.signaturePosition = signaturePosition; 
        }
 
        internal object GetValue(object[] args) 
        {
            if (args.Length <= this.signaturePosition) 
                throw new ArgumentOutOfRangeException("args");

            object arg = args[this.signaturePosition];
            if (arg == null) 
                return arg;
            Type type = arg.GetType(); 
            object val = arg; 
            if (this.locationPath.Length != 0)
            { 
                string[] split = locationPath.Split(new Char[] { '.' });
                for (int i = 1; i < split.Length; i++ )
                {
                    string s = split[i]; 
                    if (null == arg)
                        break; 
                    val = type.InvokeMember(s, BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetField | BindingFlags.GetProperty, null, arg, null, null); 

                    MemberInfo[] mInfos = type.GetMember(s, BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetField | BindingFlags.GetProperty); 

                    type = GetMemberType(mInfos[0]);
                    arg = val;
                } 
            }
            return val; 
        } 

        internal string Name 
        {
            get
            {
                return this.name; 
            }
        } 
 
        private Type GetMemberType(MemberInfo mInfo)
        { 
            Type type = null;
            switch (mInfo.MemberType)
            {
                case MemberTypes.Field: 
                    type = ((FieldInfo)mInfo).FieldType;
                    break; 
 
                case MemberTypes.Property:
                    type = ((PropertyInfo)mInfo).PropertyType; 
                    break;

                default:
                    Debug.Assert(false, "locationPath points to something other than a Field/Property"); 
                    return null;
            } 
 
            return type;
        } 
    }

    internal sealed class DefaultCorrelationProvider : ICorrelationProvider
    { 
        Type interfaceType;
 
        // map of method name to correlation properties 
        Dictionary cachedCorrelationProperties;
        object cachedCorrelationPropertiesSync = new object(); 

        // cached initializers
        // map operation to bool flag to indicate events
        Dictionary initializerCorrelationPropertys = null; 
        object initializerCorrelationPropertysSync = new object();
 
        internal DefaultCorrelationProvider(Type interfaceType) 
        {
            this.cachedCorrelationProperties = new Dictionary(); 
            this.interfaceType = interfaceType;
        }

        ICollection ICorrelationProvider.ResolveCorrelationPropertyValues(Type interfaceType, string methodName, object[] methodArgs, bool provideInitializerTokens) 
        {
            CorrelationPropertyValue[] correlationProperties = null; 
 
            if (methodArgs == null || provideInitializerTokens)
            { 
                return null; // no initializer specific token to return
            }

            this.cachedCorrelationProperties.TryGetValue(methodName, out correlationProperties); 
            if (correlationProperties == null)
            { 
                lock (this.cachedCorrelationPropertiesSync) 
                {
                    this.cachedCorrelationProperties.TryGetValue(methodName, out correlationProperties); 
                    if (correlationProperties == null)
                    {
                        correlationProperties = GetCorrelationProperties(interfaceType, methodName);
                        this.cachedCorrelationProperties.Add(methodName, correlationProperties); 
                    }
                } 
            } 

            List predicates = new List(); 
            for (int i = 0; i < correlationProperties.Length; i++)
            {
                predicates.Add(new CorrelationProperty(correlationProperties[i].Name,correlationProperties[i].GetValue(methodArgs)));
            } 

            return predicates; 
        } 

        private Dictionary InitializerCorrelationPropertys 
        {
            get
            {
                if (this.initializerCorrelationPropertys == null) 
                {
                    lock (this.initializerCorrelationPropertysSync) 
                    { 
                        if (this.initializerCorrelationPropertys == null)
                        { 
                            Dictionary members = new Dictionary();
                            // note this is separated out since we may need to distinguish between events & methods
                            foreach (EventInfo member in this.interfaceType.GetEvents())
                            { 
                                if ((member.GetCustomAttributes(typeof(CorrelationInitializerAttribute), true)).Length > 0)
                                { 
                                    members.Add(member.Name, true); 
                                }
                            } 
                            foreach (MethodInfo member in this.interfaceType.GetMethods())
                            {
                                if ((member.GetCustomAttributes(typeof(CorrelationInitializerAttribute), true)).Length > 0)
                                { 
                                    members.Add(member.Name, false);
                                } 
                            } 

                            this.initializerCorrelationPropertys = members; 
                        }
                    }
                }
                return this.initializerCorrelationPropertys; 
            }
        } 
 
 		bool ICorrelationProvider.IsInitializingMember(Type interfaceType, string memberName, object[] methodArgs)
        { 
			return InitializerCorrelationPropertys.ContainsKey(memberName);
        }

        private CorrelationPropertyValue[] GetCorrelationProperties(Type interfaceType, string methodName) 
        {
            CorrelationPropertyValue[] correlationProperties = null; 
 
            if (interfaceType.GetCustomAttributes(typeof(ExternalDataExchangeAttribute), true).Length == 0)
                throw new InvalidOperationException(SR.GetString(SR.Error_ExternalDataExchangeException,interfaceType.AssemblyQualifiedName)); 

            List correlationParamAttributes = new List();
            correlationParamAttributes.AddRange(GetCorrelationParameterAttributes(interfaceType));
 
            if (correlationParamAttributes.Count == 0)
                throw new InvalidOperationException(SR.GetString(SR.Error_CorrelationParameterException, interfaceType.AssemblyQualifiedName)); 
 
            correlationProperties = new CorrelationPropertyValue[correlationParamAttributes.Count];
 
            Dictionary corrAliases = null;
            MethodInfo methodInfo = null;

            GetMethodInfo(interfaceType, methodName, out methodInfo, out corrAliases); 

            if (methodInfo == null) 
            { 
                throw new MissingMethodException(interfaceType.AssemblyQualifiedName, methodName);
            } 

            ParameterInfo[] parameters = methodInfo.GetParameters();

            int i = 0; 
            foreach (CorrelationParameterAttribute paramAttribute in correlationParamAttributes)
            { 
                String location = paramAttribute.Name; 
                CorrelationAliasAttribute aliasAttribute = GetMatchingCorrelationAlias(paramAttribute, corrAliases, correlationParamAttributes.Count == 1);
 
                if (aliasAttribute != null)
                    location = aliasAttribute.Path;

                CorrelationPropertyValue value = GetCorrelationProperty(parameters, paramAttribute.Name, location); 
                if (value == null)
                    throw new InvalidOperationException(SR.GetString(SR.Error_CorrelationParameterException,interfaceType.AssemblyQualifiedName, paramAttribute.Name, methodName)); 
 
                correlationProperties[i++] = value;
            } 
            return correlationProperties;
        }

        private CorrelationAliasAttribute GetMatchingCorrelationAlias(CorrelationParameterAttribute paramAttribute, Dictionary correlationAliases, bool defaultParameter) 
        {
            CorrelationAliasAttribute corrAlias = null; 
 
            if (correlationAliases == null) return null;
 
            if (defaultParameter)
            {
                if (correlationAliases.TryGetValue("", out corrAlias))
                { 
                    return corrAlias;
                } 
            } 

            correlationAliases.TryGetValue(paramAttribute.Name, out corrAlias); 
            return corrAlias;
        }

        private CorrelationPropertyValue GetCorrelationProperty(ParameterInfo[] parameters, String propertyName, String location) 
        {
            string[] split = location.Split(new Char[] { '.' }); 
 
            if (split.Length == 1 && parameters.Length == 2)
            { 
                if (typeof(ExternalDataEventArgs).IsAssignableFrom(parameters[1].ParameterType))
                {
                    string aliasedLocation = "e." + location;
                    return GetCorrelationProperty(parameters, propertyName, "e", aliasedLocation); 
                }
 
            } 
            string parameterName = split[0];
 
            return GetCorrelationProperty(parameters, propertyName, parameterName, location);
        }

        private void GetMethodInfo(Type interfaceType, string methodName, out MethodInfo methodInfo, out Dictionary correlationAliases) 
        {
            correlationAliases = new Dictionary(); 
            Object[] customAttrs = null; 
            methodInfo = null;
            // check events 
            BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
            EventInfo eventInfo = interfaceType.GetEvent(methodName, bindingFlags);
            if (eventInfo != null)
            { 
                customAttrs = eventInfo.GetCustomAttributes(typeof(CorrelationAliasAttribute), true);
                if (customAttrs == null || customAttrs.Length == 0) 
                { 
                      customAttrs = eventInfo.EventHandlerType.GetCustomAttributes(typeof(CorrelationAliasAttribute), true);
                } 
                MethodInfo[] methInfo = eventInfo.EventHandlerType.GetMethods();
                methodInfo = methInfo[0];
            }
            else 
            {
                // check methods 
                methodInfo = interfaceType.GetMethod(methodName, bindingFlags); 
                if (methodInfo == null)
                { 
                    throw new MissingMethodException(interfaceType.AssemblyQualifiedName, methodName);
                }
                customAttrs = methodInfo.GetCustomAttributes(typeof(CorrelationAliasAttribute), true);
            } 

            foreach (CorrelationAliasAttribute aliasAttribute in customAttrs) 
            { 
                if (customAttrs.Length > 1)
                { 
                    Debug.Assert(aliasAttribute.Name != null);
                    if (aliasAttribute.Name == null)
                        throw new ArgumentNullException("ParameterName");
                } 
                correlationAliases.Add(aliasAttribute.Name == null ? "" : aliasAttribute.Name, aliasAttribute);
            } 
        } 

        private CorrelationPropertyValue GetCorrelationProperty(ParameterInfo[] parameters, string propertyName, string parameterName, string location) 
        {
            for (int j = 0; parameters != null && j < parameters.Length; j++)
            {
                ParameterInfo param = parameters[j]; 
                if (param.Name == parameterName)
                { 
                    // parameter match 
                    return new CorrelationPropertyValue(propertyName, location, param.Position);
                } 
            }

            return null;
        } 

        private object[] GetCorrelationParameterAttributes(Type type) 
        { 
            return type.GetCustomAttributes(typeof(CorrelationParameterAttribute), true);
        } 
    }

    internal sealed class NonCorrelatedProvider : ICorrelationProvider
    { 
        internal NonCorrelatedProvider()
        { 
        } 

        ICollection ICorrelationProvider.ResolveCorrelationPropertyValues(Type interfaceType, string methodName, object[] methodArgs, bool provideInitializerTokens) 
        {
            // non correlated
            // no values to return
            return null; 
        }
 
        bool ICorrelationProvider.IsInitializingMember(Type interfaceType, string memberName, object[] methodArgs) 
        {
            return true; 
        }
    }
}

// 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