Ejemplo n.º 1
0
        /// <summary>
        /// Gets the service entry associated with the given interface and name.
        /// </summary>
        /// <param name="self">The target <see cref="IServiceContainer"/>.</param>
        /// <param name="name">The (optional) name of the entry.</param>
        /// <param name="mode">Options.</param>
        /// <returns>The requested service entry.</returns>
        /// <exception cref="ServiceNotFoundException">If the service could not be found.</exception>
        public static AbstractServiceEntry?Get <TInterface>(this IServiceContainer self, string?name, QueryModes mode = QueryModes.Default)
        {
            if (self == null)
            {
                throw new ArgumentNullException(nameof(self));
            }

            return(self.Get(typeof(TInterface), name, mode));
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Gets the service entry associated with the given interface.
 /// </summary>
 /// <param name="self">The target <see cref="IServiceContainer"/>.</param>
 /// <param name="mode">Options.</param>
 /// <returns>The requested service entry.</returns>
 /// <exception cref="ServiceNotFoundException">If the service could not be found.</exception>
 public static AbstractServiceEntry?Get <TInterface>(this IServiceContainer self, QueryModes mode = QueryModes.Default) => self.Get <TInterface>(null, mode);
Ejemplo n.º 3
0
        public virtual AbstractServiceEntry?Get(Type serviceInterface, string?name, QueryModes mode)
        {
            CheckNotDisposed();
            Ensure.Parameter.IsNotNull(serviceInterface, nameof(serviceInterface));
            Ensure.Parameter.IsInterface(serviceInterface, nameof(serviceInterface));

            IServiceId key = MakeId(serviceInterface);

            AbstractServiceEntry existing;

            using (FLock.AcquireReaderLock())
            {
                //
                // 1. eset: Vissza tudjuk adni amit kerestunk.
                //

                if (FEntries.TryGetValue(key, out existing))
                {
                    return(existing);
                }

                //
                // 2. eset: A bejegyzes generikus parjat kell majd feldolgozni.
                //

                bool hasGenericEntry = mode.HasFlag(QueryModes.AllowSpecialization) &&
                                       serviceInterface.IsGenericType &&
                                       FEntries.TryGetValue
                                       (
                    MakeId(serviceInterface.GetGenericTypeDefinition()),
                    out existing
                                       );

                //
                // 3. eset: Egyik se jott be, vagy kivetelt v NULL-t adunk vissza.
                //

                if (!hasGenericEntry)
                {
                    return(!mode.HasFlag(QueryModes.ThrowOnError)
                        ? (AbstractServiceEntry?)null
                        : throw new ServiceNotFoundException(string.Format(Resources.Culture, Resources.SERVICE_NOT_FOUND, key.FriendlyName())));
                }
            }

            Assert(existing.IsGeneric());
            Assert(mode.HasFlag(QueryModes.AllowSpecialization));

            using (FLock.AcquireWriterLock())
            {
                //
                // Kozben vki berakta mar?
                //

                if (FEntries.TryGetValue(key, out AbstractServiceEntry? specialized))
                {
                    return(specialized);
                }

                //
                // Ha nem mi vagyunk a tulajdonosok akkor ertesitjuk a tulajdonost h tipizalja o a bejegyzest
                // majd masoljuk az uj elemet sajat magunkhoz (epp ugy mint ha "orokoltuk" vna).
                //
                // Igy lehetove tesszuk h pl singleton elettartamnal a tipizalt peldany elettartamarol is a
                // deklaralo kollekcio gondoskodjon.
                //

                if (existing.Owner != this)
                {
                    specialized = existing
                                  .Owner
                                  .Get(serviceInterface, name, mode);

                    //
                    // "specialized" lehet NULL ha a "QueryModes.ThrowOnError" nem volt beallitva es "existing"
                    // nem valositja meg a "ISupportsSpecialization" interface-t.
                    //

                    return(specialized?.CopyTo(this));
                }

                //
                // Ha mi vagyunk a tulajdonosok akkor nekunk kell tipizalni majd felvenni a bejegyzest.
                //

                if (existing is ISupportsSpecialization generic)
                {
                    //
                    // Ne az "FEntries.Add(specialized, specialized)"-ot hivjuk mert a "this.Add()" virtualis.
                    //

                    Add(specialized = generic.Specialize(serviceInterface.GetGenericArguments()));
                    return(specialized);
                }

                return(!mode.HasFlag(QueryModes.ThrowOnError)
                    ? (AbstractServiceEntry?)null
                    : throw new NotSupportedException(Resources.ENTRY_CANNOT_BE_SPECIALIZED));
            }

            IServiceId MakeId(Type iface) => new ServiceId(iface, name);
        }