/// <summary>
        /// Register a service with callback for configuration.
        /// </summary>
        /// <param name="serviceType">Type of <see cref="IDreamService"/> to register.</param>
        /// <param name="configurationCallback">Callback for modifying the created <see cref="IDreamServiceConfigurationBuilder"/> instance.</param>
        /// <returns>
        /// True if service was configured (only possible to be false if <see cref="IDreamServiceConfigurationBuilder.SkipIfExists"/> was
        /// specified and a service already exists at the configured path.
        /// </returns>
        public bool RegisterService(Type serviceType, Action <IDreamServiceConfigurationBuilder> configurationCallback)
        {
            var config = new DreamServiceConfigurationBuilder(serviceType);

            configurationCallback(config);
            return(RegisterService(config));
        }
        /// <summary>
        /// Scan the provided assembly for <see cref="IDreamService"/> that live in a namespace ending with .Services and configure them.
        /// </summary>
        /// <param name="assembly">Assembly to scan.</param>
        /// <param name="filter">Filter expression to exclude services.</param>
        /// <param name="configurationCallback">Configuration callback expression to be called for each <see cref="Type"/> to be configured.</param>
        public void ScanAssemblyForServices(Assembly assembly, Func <Type, bool> filter, Action <Type, IDreamServiceConfigurationBuilder> configurationCallback)
        {
            Func <Type, bool> defaultFilter = t => true;
            var serviceTypes = from t in assembly.GetTypes()
                               where !string.IsNullOrEmpty(t.Namespace) &&
                               t.Namespace.EndsWith(".Services") &&
                               t.IsA <IDreamService>() &&
                               t.Name.EndsWith("Service") &&
                               (filter ?? defaultFilter)(t)
                               select t;

            foreach (var serviceType in serviceTypes)
            {
                var config = new DreamServiceConfigurationBuilder(serviceType);
                if (configurationCallback != null)
                {
                    configurationCallback(serviceType, config);
                }
                if (RegisterService(config))
                {
                    continue;
                }
                var existing = _registrations[config.Path];
                throw new InvalidOperationException(string.Format("Can't register service '{0}' because '{1}' is already bound to path '{2}'",
                                                                  serviceType,
                                                                  existing.ServiceType,
                                                                  config.Path
                                                                  ));
            }
        }
 private bool RegisterService(DreamServiceConfigurationBuilder config)
 {
     lock (_registrations) {
         if (_registrations.ContainsKey(config.Path))
         {
             if (config.SkipServiceIfExists)
             {
                 return(false);
             }
         }
         _registrations[config.Path] = config;
     }
     return(true);
 }