/// <summary> /// Returns true if the entry is intended to internal use. /// </summary> public static bool IsInternal(this AbstractServiceEntry self) { if (self is null) { throw new ArgumentNullException(nameof(self)); } return(self.Name?.StartsWith(Consts.INTERNAL_SERVICE_NAME_PREFIX, StringComparison.Ordinal) == true); }
/// <summary> /// The service was registered via <see cref="IServiceContainerBasicExtensions.Instance(IServiceContainer, Type, string, object, bool)"/> call. /// </summary> public static bool IsInstance(this AbstractServiceEntry self) { if (self is null) { throw new ArgumentNullException(nameof(self)); } return(self.Lifetime == Lifetime.Instance); }
/// <summary> /// The service was registered via <see cref="IServiceContainerBasicExtensions.Service(IServiceContainer, Type, string, Type, Lifetime)"/> call. /// </summary> public static bool IsService(this AbstractServiceEntry self) { if (self is null) { throw new ArgumentNullException(nameof(self)); } return(self.Implementation != null); }
/// <summary> /// The service was registered via <see cref="IServiceContainerBasicExtensions.Factory(IServiceContainer, Type, string, Func{IInjector, Type, object}, Lifetime)"/> call. /// </summary> public static bool IsFactory(this AbstractServiceEntry self) { if (self is null) { throw new ArgumentNullException(nameof(self)); } return(!self.IsService() && self.Factory != null); }
/// <summary> /// Hooks into the instantiating process to let you decorate the original service. Useful when you want to add additional functionality (e.g. parameter validation). /// </summary> /// <param name="self">The target <see cref="IServiceContainer"/>.</param> /// <param name="iface">The service to be decorated.</param> /// <param name="name">The (optional) name of the service.</param> /// <param name="decorator">The decorator funtion. It must return the decorated instance. The original instance can be accessed via the 3rd parameter of the decorator function.</param> /// <returns>The container itself.</returns> /// <remarks>You can't create proxies against generic, instance or not owned entries. A service can be decorated multiple times.</remarks> /// <exception cref="InvalidOperationException">When proxying not allowed (see above).</exception> public static IServiceContainer Proxy(this IServiceContainer self, Type iface, string?name, Func <IInjector, Type, object, object> decorator) { if (self == null) { throw new ArgumentNullException(nameof(self)); } if (decorator == null) { throw new ArgumentNullException(nameof(decorator)); } // // - Get() validalja az "iface" parametert // - "QueryModes.ThrowOnError" miatt "entry" sose NULL // AbstractServiceEntry entry = self.Get(iface, name, QueryModes.AllowSpecialization | QueryModes.ThrowOnError) !; if (entry.Owner != self) { throw new InvalidOperationException(Resources.INAPROPRIATE_OWNERSHIP); } if (entry is not ISupportsProxying setter || setter.Factory == null) { // // Generikus szerviz, Abstract(), Instance() eseten a metodus nem ertelmezett. // throw new InvalidOperationException(Resources.PROXYING_NOT_SUPPORTED); } // // Bovitjuk a hivasi lancot a decorator-al. // Func <IInjector, Type, object> oldFactory = setter.Factory; setter.Factory = (injector, type) => decorator(injector, type, oldFactory(injector, type)); return(self); }