ServiceManager.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 / NetFx40 / Tools / System.Activities.Presentation / System / Activities / Presentation / Base / Core / ServiceManager.cs / 1305376 / ServiceManager.cs

                            namespace System.Activities.Presentation { 

    using System.Activities.Presentation.Internal.Properties;
    using System;
    using System.Collections; 
    using System.Collections.Generic;
    using System.Diagnostics; 
    using System.Diagnostics.CodeAnalysis; 
    using System.Globalization;
    using System.Activities.Presentation; 

    /// 
    /// The service manager implements IServiceProvider and provides access
    /// to services offered by the editing context. 
    /// 
    /// Suppressing FxCop from complaining about our use of naming, since it has been approved 
    [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")] 
    public abstract class ServiceManager : IServiceProvider, IEnumerable
    { 

        /// 
        /// Creates a new ServiceManager.
        ///  
        protected ServiceManager() {}
 
        ///  
        /// Returns true if the service manager contains a service of the given type.
        ///  
        /// The type of service to check.
        /// True if a service of type serviceType has been published.
        /// if serviceType is null.
        public abstract bool Contains(Type serviceType); 

        ///  
        /// Returns true if the service manager contains a service of the given type. 
        /// 
        /// The type of service to check. 
        /// True if a service of type TServiceType has been published.
        [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")]
        public bool Contains()
        { 
            return Contains(typeof(TServiceType));
        } 
 
        /// 
        /// Retrives the requested service.  Unlike GetService, GetRequiredService 
        /// throws a NotSupportedException if the service isn’t available.  The reason
        /// we provide this method, and not a normal GetService method is our wish to
        /// move services to a more reliable contract.
        ///  
        /// The type of service to retrieve.
        /// An instance of the service.  This never returns null. 
        /// if there is no service of the given type. 
        [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")]
        [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")] 
        public TServiceType GetRequiredService()
        {
            TServiceType service = GetService();
            if (service == null) { 
                throw FxTrace.Exception.AsError(new NotSupportedException(
                    string.Format(CultureInfo.CurrentCulture, 
                    Resources.Error_RequiredService, typeof(TServiceType).FullName))); 
            }
            return service; 
        }

        /// 
        /// Retrives the requested service.  This method returns null if the service could not be located. 
        /// 
        /// The type of service to retrieve. 
        /// An instance of the service, or null if the service has not been published. 
        [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")]
        public TServiceType GetService() 
        {
            object service = GetService(typeof(TServiceType));
            return (TServiceType)service;
        } 

        ///  
        /// Retrives the requested service.  This method returns null if the service could not be located. 
        /// 
        /// The type of service to retrieve. 
        /// An instance of the service, or null if the service has not been published.
        /// If serviceType is null.
        public abstract object GetService(Type serviceType);
 
        /// 
        /// Retrives an enumerator that can be used to enumerate all of the services that this 
        /// service manager publishes. 
        /// 
        /// An enumeration of published services. 
        public abstract IEnumerator GetEnumerator();

        /// 
        /// Calls back on the provided callback when someone has published the requested service. 
        /// If the service was already available, this method invokes the callback immediately.
        /// 
        /// A generic version of this method is provided for convenience, and calls the non-generic 
        /// method with appropriate casts.
        ///  
        /// The type of service to subscribe to.
        /// A callback that will be notified when the service is available.
        /// If serviceType or callback is null.
        public abstract void Subscribe(Type serviceType, SubscribeServiceCallback callback); 

        ///  
        /// Calls back on the provided callback when someone has published the requested service. 
        /// If the service was already available, this method invokes the callback immediately.
        /// 
        /// A generic version of this method is provided for convenience, and calls the non-generic
        /// method with appropriate casts.
        /// 
        /// The type of service to subscribe. 
        /// A callback that will be invoked when the service is available.
        /// If callback is null. 
        [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")] 
        public void Subscribe(SubscribeServiceCallback callback)
        { 
            if (callback == null) throw FxTrace.Exception.ArgumentNull("callback");

            // Call the standard Subscribe method and use a generic proxy
            SubscribeProxy proxy = new SubscribeProxy(callback); 
            Subscribe(typeof(TServiceType), proxy.Callback);
        } 
 
        /// 
        /// Publishes the given service type, but does not declare an instance yet.  When someone 
        /// requests the service the PublishServiceCallback will be invoked to create the instance.
        /// The callback is only invoked once and after that the instance it returned is cached.
        ///
        /// A generic version of this method is provided for convenience, and calls the non-generic 
        /// method with appropriate casts.
        ///  
        /// The type of service to publish. 
        /// A callback that will be invoked when an instance of the service is needed.
        /// If serviceType or callback is null. 
        /// If serviceType has already been published.
        public abstract void Publish(Type serviceType, PublishServiceCallback callback);

        ///  
        /// Publishes the given service.  Once published, the service instance remains in the
        /// service manager until the editing context is disposed. 
        ///  
        /// The type of service to publish.
        /// An instance of the service. 
        /// If serviceType or serviceInstance is null.
        /// If serviceInstance does not derive from or implement serviceType, or if serviceType has already been published.
        public abstract void Publish(Type serviceType, object serviceInstance);
 
        /// 
        /// Publishes the given service type, but does not declare an instance yet.  When someone 
        /// requests the service the PublishServiceCallback will be invoked to create the instance. 
        /// The callback is only invoked once and after that the instance it returned is cached.
        ///  
        /// The type of service to publish.
        /// A callback to be invoked when the service is required.
        /// If callback is null.
        /// If TServiceType has already been published. 
        [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")]
        public void Publish(PublishServiceCallback callback) 
        { 
            if (callback == null) throw FxTrace.Exception.ArgumentNull("callback");
 
            // Call the standard Subscribe method and use a generic proxy
            PublishProxy proxy = new PublishProxy(callback);
            Publish(typeof(TServiceType), proxy.Callback);
        } 

        ///  
        /// Publishes the given service.  Once published, the service instance remains in the 
        /// service manager until the editing context is disposed.
        ///  
        /// The type of service to publish.
        /// The instance of the service to publish.
        /// If TServiceType has already been published.
        public void Publish(TServiceType serviceInstance) { 
            if (serviceInstance == null) throw FxTrace.Exception.ArgumentNull("serviceInstance");
            Publish(typeof(TServiceType), serviceInstance); 
        } 

        ///  
        /// Removes a subscription for the TServiceType.
        /// 
        /// The type of service to remove the subscription from.
        /// The callback object to remove from the subscription. 
        /// If callback is null.
        [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")] 
        public void Unsubscribe(SubscribeServiceCallback callback) 
        {
            if (callback == null) throw FxTrace.Exception.ArgumentNull("callback"); 
            SubscribeProxy proxy = new SubscribeProxy(callback);
            Unsubscribe(typeof(TServiceType), proxy.Callback);
        }
 
        /// 
        /// Removes a subscription for the serviceType. 
        ///  
        /// The type of service to remove the subscription from.
        /// The callback object to remove from the subscription. 
        /// If serviceType or callback is null.
        public abstract void Unsubscribe(Type serviceType, SubscribeServiceCallback callback);

        ///  
        ///     This is a helper method that returns the target object for a delegate.
        ///     If the delegate was created to proxy a generic delegate, this will correctly 
        ///     return the original object, not the proxy. 
        /// 
        /// The delegate to get the target for. 
        /// The object that is the callback target.  This can return null if the callback represents a static object.
        /// If callback is null.
        protected static object GetTarget(Delegate callback) {
            if (callback == null) throw FxTrace.Exception.ArgumentNull("callback"); 
            ICallbackProxy proxy = callback.Target as ICallbackProxy;
            if (proxy != null) { 
                return proxy.OriginalTarget; 
            }
 
            return callback.Target;
        }

        ///  
        ///     This is a helper method that performs a Delegate.Remove, but knows
        ///     how to unwrap delegates that are proxies to generic callbacks.  Use 
        ///     this in your Unsubscribe implementations. 
        /// 
        /// The existing delegate to remove the callback from. 
        /// The callback to remove.
        /// A new value to assign to the existing delegate.
        protected static Delegate RemoveCallback(Delegate existing, Delegate toRemove) {
            if (existing == null) return null; 
            if (toRemove == null) return existing;
 
            ICallbackProxy toRemoveProxy = toRemove.Target as ICallbackProxy; 
            if (toRemoveProxy == null) {
                // The item to be removed is a normal delegate.  Just call 
                // Delegate.Remove
                return Delegate.Remove(existing, toRemove);
            }
 
            toRemove = toRemoveProxy.OriginalDelegate;
 
            Delegate[] invocationList = existing.GetInvocationList(); 
            bool removedItems = false;
 
            for (int idx = 0; idx < invocationList.Length; idx++) {
                Delegate item = invocationList[idx];
                ICallbackProxy itemProxy = item.Target as ICallbackProxy;
                if (itemProxy != null) { 
                    item = itemProxy.OriginalDelegate;
                } 
 
                if (item.Equals(toRemove)) {
                    invocationList[idx] = null; 
                    removedItems = true;
                }
            }
 
            if (removedItems) {
                // We must create a new delegate containing the 
                // invocation list that is is left 
                existing = null;
                foreach (Delegate d in invocationList) { 
                    if (d != null) {
                        if (existing == null) {
                            existing = d;
                        } 
                        else {
                            existing = Delegate.Combine(existing, d); 
                        } 
                    }
                } 
            }

            return existing;
        } 

        ///  
        /// Implementation of default IEnumerable. 
        /// 
        IEnumerator IEnumerable.GetEnumerator() { 
            return GetEnumerator();
        }

        ///  
        /// This is a simple proxy that converts a non-generic publish callback to a generic
        /// one. 
        ///  
        /// 
        private class PublishProxy { 
            private PublishServiceCallback _genericCallback;

            internal PublishProxy(PublishServiceCallback callback) {
                _genericCallback = callback; 
            }
 
            internal PublishServiceCallback Callback { 
                get {
                    return new PublishServiceCallback(PublishService); 
                }
            }

            private object PublishService(Type serviceType) { 

                if (serviceType == null) throw FxTrace.Exception.ArgumentNull("serviceType"); 
 
                if (serviceType != typeof(TServiceType)) {
                    // This is an invalid publisher 
                    throw FxTrace.Exception.AsError(new InvalidOperationException(string.Format(
                        CultureInfo.CurrentCulture,
                        Resources.Error_IncorrectServiceType,
                        typeof(ServiceManager).FullName, 
                        typeof(TServiceType).FullName,
                        serviceType.FullName))); 
                } 

                object service = _genericCallback(); 

                if (service == null) {
                    throw FxTrace.Exception.AsError(new InvalidOperationException(
                        string.Format( 
                        CultureInfo.CurrentCulture,
                        Resources.Error_NullService, 
                        _genericCallback.Method.DeclaringType.FullName, 
                        serviceType.FullName)));
                } 

                if (!serviceType.IsInstanceOfType(service)) {
                    throw FxTrace.Exception.AsError(new InvalidOperationException(
                        string.Format( 
                        CultureInfo.CurrentCulture,
                        Resources.Error_IncorrectServiceType, 
                        _genericCallback.Method.DeclaringType.FullName, 
                        serviceType.FullName,
                        service.GetType().FullName))); 
                }

                return service;
            } 
        }
 
        ///  
        /// This is a simple proxy that converts a non-generic subscribe callback to a generic
        /// one. 
        /// 
        /// 
        private class SubscribeProxy : ICallbackProxy {
            private SubscribeServiceCallback _genericCallback; 

            internal SubscribeProxy(SubscribeServiceCallback callback) { 
                _genericCallback = callback; 
            }
 
            internal SubscribeServiceCallback Callback {
                get {
                    return new SubscribeServiceCallback(SubscribeService);
                } 
            }
 
 
            private void SubscribeService(Type serviceType, object service) {
 
                if (serviceType == null) throw FxTrace.Exception.ArgumentNull("serviceType");
                if (service == null) throw FxTrace.Exception.ArgumentNull("service");

                if (!typeof(TServiceType).IsInstanceOfType(service)) { 
                    // This is an invalid subscriber
                    throw FxTrace.Exception.AsError(new InvalidOperationException(string.Format( 
                        CultureInfo.CurrentCulture, 
                        Resources.Error_IncorrectServiceType,
                        typeof(TServiceType).FullName, 
                        serviceType.FullName)));
                }

                _genericCallback((TServiceType)service); 
            }
 
            Delegate ICallbackProxy.OriginalDelegate { 
                get { return _genericCallback; }
            } 

            object ICallbackProxy.OriginalTarget {
                get {
                    return _genericCallback.Target; 
                }
            } 
        } 

        private interface ICallbackProxy { 
            Delegate OriginalDelegate { get; }
            object OriginalTarget { get; }
        }
    } 
}

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


                        

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