using System; using System.Collections.Generic; using System.Linq; using Unosquare.Swan.Exceptions; namespace Unosquare.Swan.Components { /// /// Registration options for "fluent" API. /// public sealed class RegisterOptions { private readonly TypesConcurrentDictionary _registeredTypes; private readonly DependencyContainer.TypeRegistration _registration; /// /// Initializes a new instance of the class. /// /// The registered types. /// The registration. public RegisterOptions(TypesConcurrentDictionary registeredTypes, DependencyContainer.TypeRegistration registration) { this._registeredTypes = registeredTypes; this._registration = registration; } /// /// Make registration a singleton (single instance) if possible. /// /// A registration options for fluent API. /// Generic constraint registration exception. public RegisterOptions AsSingleton() { ObjectFactoryBase currentFactory = this._registeredTypes.GetCurrentFactory(this._registration); if(currentFactory == null) { throw new DependencyContainerRegistrationException(this._registration.Type, "singleton"); } return this._registeredTypes.AddUpdateRegistration(this._registration, currentFactory.SingletonVariant); } /// /// Make registration multi-instance if possible. /// /// A registration options for fluent API. /// Generic constraint registration exception. public RegisterOptions AsMultiInstance() { ObjectFactoryBase currentFactory = this._registeredTypes.GetCurrentFactory(this._registration); if(currentFactory == null) { throw new DependencyContainerRegistrationException(this._registration.Type, "multi-instance"); } return this._registeredTypes.AddUpdateRegistration(this._registration, currentFactory.MultiInstanceVariant); } /// /// Make registration hold a weak reference if possible. /// /// A registration options for fluent API. /// Generic constraint registration exception. public RegisterOptions WithWeakReference() { ObjectFactoryBase currentFactory = this._registeredTypes.GetCurrentFactory(this._registration); if(currentFactory == null) { throw new DependencyContainerRegistrationException(this._registration.Type, "weak reference"); } return this._registeredTypes.AddUpdateRegistration(this._registration, currentFactory.WeakReferenceVariant); } /// /// Make registration hold a strong reference if possible. /// /// A registration options for fluent API. /// Generic constraint registration exception. public RegisterOptions WithStrongReference() { ObjectFactoryBase currentFactory = this._registeredTypes.GetCurrentFactory(this._registration); if(currentFactory == null) { throw new DependencyContainerRegistrationException(this._registration.Type, "strong reference"); } return this._registeredTypes.AddUpdateRegistration(this._registration, currentFactory.StrongReferenceVariant); } } /// /// Registration options for "fluent" API when registering multiple implementations. /// public sealed class MultiRegisterOptions { private IEnumerable _registerOptions; /// /// Initializes a new instance of the class. /// /// The register options. public MultiRegisterOptions(IEnumerable registerOptions) => this._registerOptions = registerOptions; /// /// Make registration a singleton (single instance) if possible. /// /// A registration multi-instance for fluent API. /// Generic Constraint Registration Exception. public MultiRegisterOptions AsSingleton() { this._registerOptions = this.ExecuteOnAllRegisterOptions(ro => ro.AsSingleton()); return this; } /// /// Make registration multi-instance if possible. /// /// A registration multi-instance for fluent API. /// Generic Constraint Registration Exception. public MultiRegisterOptions AsMultiInstance() { this._registerOptions = this.ExecuteOnAllRegisterOptions(ro => ro.AsMultiInstance()); return this; } private IEnumerable ExecuteOnAllRegisterOptions( Func action) => this._registerOptions.Select(action).ToList(); } }