예제 #1
0
            /// <summary>
            /// Initializes a new instance of the <see cref="ServiceVertex"/> class.
            /// </summary>
            /// <param name="service">The service.</param>
            public ServiceVertex(KernelService service)
            {
                {
                    Debug.Assert(service != null, "The service should exist");
                }

                Service = service;
            }
예제 #2
0
            /// <summary>
            /// Initializes a new instance of the <see cref="ServiceVertex"/> class.
            /// </summary>
            /// <param name="service">The service.</param>
            public ServiceVertex(KernelService service)
            {
                {
                    Debug.Assert(service != null, "The service should exist");
                }

                Service = service;
            }
예제 #3
0
            /// <summary>
            /// Initializes a new instance of the <see cref="ConnectionMap"/> class.
            /// </summary>
            /// <param name="requestedType">Type of the requested service.</param>
            /// <param name="appliedType">Type of the applied service.</param>
            public ConnectionMap(Type requestedType, KernelService appliedType)
            {
                {
                    Debug.Assert(requestedType != null, "A requested type must be provided.");
                    Debug.Assert(appliedType != null, "An applied type must be provided.");
                }

                Requested = requestedType;
                Applied = appliedType;
            }
예제 #4
0
            /// <summary>
            /// Initializes a new instance of the <see cref="ConnectionMap"/> class.
            /// </summary>
            /// <param name="requestedType">Type of the requested service.</param>
            /// <param name="appliedType">Type of the applied service.</param>
            public ConnectionMap(Type requestedType, KernelService appliedType)
            {
                {
                    Debug.Assert(requestedType != null, "A requested type must be provided.");
                    Debug.Assert(appliedType != null, "An applied type must be provided.");
                }

                Requested = requestedType;
                Applied   = appliedType;
            }
예제 #5
0
        /// <summary>
        /// Gets the dependency services that are currently available based on the given collection of dependencies.
        /// </summary>
        /// <param name="demandedServices">The collection of types which should be matched up with the installed services.</param>
        /// <returns>
        /// A collection containing a mapping between the demanded dependency and the service that would
        /// serve for this dependency.
        /// </returns>
        /// <design>
        /// Note that the current connection strategy only works if there are no demands for duplicates OR
        /// services with the same interfaces.
        /// </design>
        private IEnumerable <KeyValuePair <Type, KernelService> > GetInstalledDependencies(IEnumerable <Type> demandedServices)
        {
            // Create a copy of the available service list. Then when we
            // select a service we'll remove it from this list.
            var available = new List <KernelService>(from service in m_Services select service.Value);

            // Dependencies have just gotten a whole lot more complex
            // We want to be able to match up interfaces & abstract classes too
            // The problem is that we only want to pass each service only once
            var result = new List <KeyValuePair <Type, KernelService> >();

            foreach (var dependency in demandedServices)
            {
                KernelService selected = null;
                foreach (var storedService in available)
                {
                    if (dependency.IsAssignableFrom(storedService.GetType()))
                    {
                        selected = storedService;
                        break;
                    }
                }

                if (selected != null)
                {
                    available.Remove(selected);
                    result.Add(new KeyValuePair <Type, KernelService>(dependency, selected));
                }

                if (available.Count == 0)
                {
                    break;
                }
            }

            return(result);
        }
예제 #6
0
 /// <summary>
 /// Provides one of the services on which the current service depends.
 /// </summary>
 /// <param name="dependency">The dependency service.</param>
 public virtual void ConnectTo(KernelService dependency)
 {
     // Do nothing here ...
 }
예제 #7
0
 /// <summary>
 /// Resets this instance.
 /// </summary>
 internal void Reset()
 {
     m_Connection = null;
 }
예제 #8
0
 /// <summary>
 /// Provides one of the services on which the current service depends.
 /// </summary>
 /// <param name="dependency">The dependency service.</param>
 public override void ConnectTo(KernelService dependency)
 {
     m_Connection = dependency;
 }
예제 #9
0
 /// <summary>
 /// Resets this instance.
 /// </summary>
 internal void Reset()
 {
     m_Connection = null;
 }
예제 #10
0
 /// <summary>
 /// Provides one of the services on which the current service depends.
 /// </summary>
 /// <param name="dependency">The dependency service.</param>
 public override void ConnectTo(KernelService dependency)
 {
     m_Connection = dependency;
 }
예제 #11
0
        /// <summary>
        /// Gets the services that depend on the specified service type.
        /// </summary>
        /// <param name="service">The service type.</param>
        /// <returns>
        /// A collection containing a mapping between the demanded dependency and the service that would
        /// serve for this dependency.
        /// </returns>
        private IEnumerable <KeyValuePair <Type, KernelService> > GetDependentServices(KernelService service)
        {
            var result = new List <KeyValuePair <Type, KernelService> >();

            foreach (var map in m_Services)
            {
                var dependencyHolder = map.Value as IHaveServiceDependencies;
                if (dependencyHolder != null)
                {
                    foreach (var dependency in dependencyHolder.ServicesToConnectTo())
                    {
                        if (dependency.IsAssignableFrom(service.GetType()))
                        {
                            result.Add(new KeyValuePair <Type, KernelService>(dependency, map.Value));
                            break;
                        }
                    }
                }
            }

            return(result);
        }
예제 #12
0
        /// <summary>
        /// Installs the specified service.
        /// </summary>
        /// <param name="service">The service which should be installed.</param>
        /// <remarks>
        /// <para>
        /// Only services that are 'installed' can be used by the service manager.
        /// Services that have not been installed are simply unknown to the service
        /// manager.
        /// </para>
        /// <para>
        /// Note that only one instance for each <c>Type</c> can be provided to
        /// the service manager.
        /// </para>
        /// </remarks>
        /// <exception cref="ArgumentNullException">
        ///     Thrown if <paramref name="service"/> is <see langword="null" />.
        /// </exception>
        public void Install(KernelService service)
        {
            {
                Enforce.Argument(() => service);
            }

            if ((m_State != StartupState.NotStarted) && (m_State != StartupState.Started))
            {
                throw new KernelNotInInstallReadyStateException();
            }

            if (m_Services.ContainsKey(service.GetType()))
            {
                throw new ServiceTypeAlreadyInstalledException();
            }

            var dependencyHolder = service as IHaveServiceDependencies;

            if (dependencyHolder != null)
            {
                if (dependencyHolder.ServicesToConnectTo().Contains(dependencyHolder.GetType()))
                {
                    throw new ServiceCannotDependOnItselfException();
                }

                if (dependencyHolder.ServicesToConnectTo().Contains(typeof(KernelService)))
                {
                    throw new ServiceCannotDependOnGenericKernelServiceException();
                }

                var selectedService = GetInstalledDependencies(dependencyHolder.ServicesToConnectTo());
                foreach (var map in selectedService)
                {
                    if (!m_Connections.ContainsKey(service))
                    {
                        m_Connections.Add(service, new List <ConnectionMap>());
                    }

                    var connection = m_Connections[service];
                    connection.Add(new ConnectionMap(map.Key, map.Value));
                    dependencyHolder.ConnectTo(map.Value);
                }
            }

            var selectedServices = GetDependentServices(service);

            foreach (var map in selectedServices)
            {
                if (!m_Connections.ContainsKey(map.Value))
                {
                    m_Connections.Add(map.Value, new List <ConnectionMap>());
                }

                var connection = m_Connections[map.Value];
                connection.Add(new ConnectionMap(map.Key, service));

                var dependent = map.Value as IHaveServiceDependencies;
                Debug.Assert(dependent != null, "The service should be able to handle dependencies.");

                dependent.ConnectTo(service);
            }

            m_Services.Add(service.GetType(), service);
        }
예제 #13
0
 /// <summary>
 /// Provides one of the services on which the current service depends.
 /// </summary>
 /// <param name="dependency">The dependency service.</param>
 public virtual void ConnectTo(KernelService dependency)
 {
     // Do nothing here ...
 }
예제 #14
0
        /// <summary>
        /// Gets the services that depend on the specified service type.
        /// </summary>
        /// <param name="service">The service type.</param>
        /// <returns>
        /// A collection containing a mapping between the demanded dependency and the service that would
        /// serve for this dependency.
        /// </returns>
        private IEnumerable<KeyValuePair<Type, KernelService>> GetDependentServices(KernelService service)
        {
            var result = new List<KeyValuePair<Type, KernelService>>();
            foreach (var map in m_Services)
            {
                var dependencyHolder = map.Value as IHaveServiceDependencies;
                if (dependencyHolder != null)
                {
                    foreach (var dependency in dependencyHolder.ServicesToConnectTo())
                    {
                        if (dependency.IsAssignableFrom(service.GetType()))
                        {
                            result.Add(new KeyValuePair<Type, KernelService>(dependency, map.Value));
                            break;
                        }
                    }
                }
            }

            return result;
        }
예제 #15
0
        /// <summary>
        /// Installs the specified service.
        /// </summary>
        /// <param name="service">The service which should be installed.</param>
        /// <remarks>
        /// <para>
        /// Only services that are 'installed' can be used by the service manager.
        /// Services that have not been installed are simply unknown to the service
        /// manager.
        /// </para>
        /// <para>
        /// Note that only one instance for each <c>Type</c> can be provided to
        /// the service manager.
        /// </para>
        /// </remarks>
        /// <exception cref="ArgumentNullException">
        ///     Thrown if <paramref name="service"/> is <see langword="null" />.
        /// </exception>
        public void Install(KernelService service)
        {
            {
                Enforce.Argument(() => service);
            }

            if ((m_State != StartupState.NotStarted) && (m_State != StartupState.Started))
            {
                throw new KernelNotInInstallReadyStateException();
            }

            if (m_Services.ContainsKey(service.GetType()))
            {
                throw new ServiceTypeAlreadyInstalledException();
            }

            var dependencyHolder = service as IHaveServiceDependencies;
            if (dependencyHolder != null)
            {
                if (dependencyHolder.ServicesToConnectTo().Contains(dependencyHolder.GetType()))
                {
                    throw new ServiceCannotDependOnItselfException();
                }

                if (dependencyHolder.ServicesToConnectTo().Contains(typeof(KernelService)))
                {
                    throw new ServiceCannotDependOnGenericKernelServiceException();
                }

                var selectedService = GetInstalledDependencies(dependencyHolder.ServicesToConnectTo());
                foreach (var map in selectedService)
                {
                    if (!m_Connections.ContainsKey(service))
                    {
                        m_Connections.Add(service, new List<ConnectionMap>());
                    }

                    var connection = m_Connections[service];
                    connection.Add(new ConnectionMap(map.Key, map.Value));
                    dependencyHolder.ConnectTo(map.Value);
                }
            }

            var selectedServices = GetDependentServices(service);
            foreach (var map in selectedServices)
            {
                if (!m_Connections.ContainsKey(map.Value))
                {
                    m_Connections.Add(map.Value, new List<ConnectionMap>());
                }

                var connection = m_Connections[map.Value];
                connection.Add(new ConnectionMap(map.Key, service));

                var dependent = map.Value as IHaveServiceDependencies;
                Debug.Assert(dependent != null, "The service should be able to handle dependencies.");

                dependent.ConnectTo(service);
            }

            m_Services.Add(service.GetType(), service);
        }