/// <summary> /// Registers all concrete, non-generic types (both public and internal) that are defined in the given /// set of <paramref name="assemblies"/> and that implement the given <paramref name="serviceType"/> /// with a default lifestyle and register them as a collection of <paramref name="serviceType"/>. /// Unless overridden using a custom /// <see cref="ContainerOptions.LifestyleSelectionBehavior">LifestyleSelectionBehavior</see>, the /// default lifestyle is <see cref="Lifestyle.Transient">Transient</see>. /// <see cref="TypesToRegisterOptions.IncludeComposites">Composites</see>, /// <see cref="TypesToRegisterOptions.IncludeDecorators">decorators</see> and /// <see cref="TypesToRegisterOptions.IncludeGenericTypeDefinitions">generic type definitions</see> /// will be excluded from registration. /// </summary> /// <param name="serviceType">The element type of the collections to register. This can be either /// a non-generic, closed-generic or open-generic type.</param> /// <param name="assemblies">A list of assemblies that will be searched.</param> /// <exception cref="ArgumentNullException">Thrown when one of the supplied arguments contain a null /// reference (Nothing in VB).</exception> public void RegisterCollection(Type serviceType, IEnumerable <Assembly> assemblies) { var compositesExcluded = new TypesToRegisterOptions { IncludeComposites = false }; var types = this.GetTypesToRegister(serviceType, assemblies, compositesExcluded); this.RegisterCollection(serviceType, types); }
/// <summary> /// Returns all concrete types that are located in the supplied <paramref name="assemblies"/> /// and implement or inherit from the supplied <paramref name="serviceType"/> and match the specified /// <paramref name="options."/>. <paramref name="serviceType"/> can be an open-generic type. /// </summary> /// <remarks> /// Use this method when you need influence the types that are registered using /// <see cref="Register(System.Type, IEnumerable{System.Reflection.Assembly})">Register</see>. /// The <b>Register</b> overloads that take a collection of <see cref="Assembly"/> /// objects use this method internally to get the list of types that need to be registered. Instead of /// calling such overload, you can call an overload that takes a list of <see cref="System.Type"/> objects /// and pass in a filtered result from this <b>GetTypesToRegister</b> method. /// <code lang="cs"><![CDATA[ /// var container = new Container(); /// /// var assemblies = new[] { typeof(ICommandHandler<>).Assembly }; /// var options = new TypesToRegisterOptions { IncludeGenericTypeDefinitions: true }; /// var types = container.GetTypesToRegister(typeof(ICommandHandler<>), assemblies, options) /// .Where(type => type.IsPublic); /// /// container.Register(typeof(ICommandHandler<>), types); /// ]]></code> /// This example calls the <b>GetTypesToRegister</b> method to request a list of concrete implementations /// of the <b>ICommandHandler<T></b> interface from the assembly of that interface. After that /// all internal types are filtered out. This list is supplied to the /// <see cref="Container.Register(System.Type,IEnumerable{System.Type})">Register(Type, IEnumerable<Type>)</see> /// overload to finish the registration. /// </remarks> /// <param name="serviceType">The base type or interface to find derived types for. This can be both /// a non-generic and open-generic type.</param> /// <param name="assemblies">A list of assemblies that will be searched.</param> /// <param name="options">The options.</param> /// <returns>A collection of types.</returns> /// <exception cref="ArgumentNullException">Thrown when one of the arguments contain a null reference. /// </exception> public IEnumerable <Type> GetTypesToRegister( Type serviceType, IEnumerable <Assembly> assemblies, TypesToRegisterOptions options) { Requires.IsNotNull(serviceType, nameof(serviceType)); Requires.IsNotNull(assemblies, nameof(assemblies)); Requires.IsNotNull(options, nameof(options)); Requires.IsNotPartiallyClosed(serviceType, nameof(serviceType)); return(this.GetTypesToRegisterInternal(serviceType, assemblies, options).ToArray()); }
private IEnumerable <Type> GetTypesToRegisterInternal( Type serviceType, IEnumerable <Assembly> assemblies, TypesToRegisterOptions options) => from assembly in assemblies.Distinct() where !assembly.IsDynamic from type in GetTypesFromAssembly(assembly) where Types.IsConcreteType(type) where options.IncludeGenericTypeDefinitions || !type.IsGenericTypeDefinition() where Types.ServiceIsAssignableFromImplementation(serviceType, type) let ctor = this.SelectImplementationTypeConstructorOrNull(type) where ctor is null || options.IncludeDecorators || !Types.IsDecorator(serviceType, ctor) where ctor is null || options.IncludeComposites || !Types.IsComposite(serviceType, ctor) select type;
private Type[] GetNonGenericTypesToRegisterForOneToOneMapping(Type openGenericServiceType, IEnumerable<Assembly> assemblies, out Type[] skippedDecorators) { var options = new TypesToRegisterOptions { IncludeDecorators = true }; var typesIncludingDecorators = this.GetTypesToRegister(openGenericServiceType, assemblies, options); var partitions = typesIncludingDecorators.Partition(type => this.IsDecorator(openGenericServiceType, type)); skippedDecorators = partitions.Item1; return partitions.Item2; }
GetNonGenericTypesToRegisterForOneToOneMapping( Type openGenericServiceType, IEnumerable <Assembly> assemblies) { var options = new TypesToRegisterOptions { IncludeDecorators = true }; Type[] typesIncludingDecorators = this.GetTypesToRegisterInternal(openGenericServiceType, assemblies, options).ToArray(); var partitions = typesIncludingDecorators.Partition(type => !this.IsDecorator(openGenericServiceType, type)); return(new NonGenericTypesToRegisterForOneToOneMappingResults( implementationTypes: partitions.Item1, skippedDecorators: partitions.Item2)); }
/// <summary> /// Returns all concrete types that are located in the supplied <paramref name="assemblies"/> /// and implement or inherit from the supplied <paramref name="serviceType"/> and match the specified /// <paramref name="options."/>. <paramref name="serviceType"/> can be an open-generic type. /// </summary> /// <remarks> /// Use this method when you need influence the types that are registered using /// <see cref="Register(System.Type, IEnumerable{System.Reflection.Assembly})">Register</see>. /// The <b>Register</b> overloads that take a collection of <see cref="Assembly"/> /// objects use this method internally to get the list of types that need to be registered. Instead of /// calling such overload, you can call an overload that takes a list of <see cref="System.Type"/> objects /// and pass in a filtered result from this <b>GetTypesToRegister</b> method. /// <code lang="cs"><![CDATA[ /// var container = new Container(); /// /// var assemblies = new[] { typeof(ICommandHandler<>).Assembly }; /// var options = new TypesToRegisterOptions { IncludeGenericTypeDefinitions: true }; /// var types = container.GetTypesToRegister(typeof(ICommandHandler<>), assemblies, options) /// .Where(type => !type.IsPublic); /// /// container.Register(typeof(ICommandHandler<>), types); /// ]]></code> /// This example calls the <b>GetTypesToRegister</b> method to request a list of concrete implementations /// of the <b>ICommandHandler<T></b> interface from the assembly of that interface. After that /// all internal types are filtered out. This list is supplied to the /// <see cref="Container.Register(System.Type,IEnumerable{System.Type})">Register(Type, IEnumerable<Type>)</see> /// overload to finish the registration. /// </remarks> /// <param name="serviceType">The base type or interface to find derived types for. This can be both /// a non-generic and open-generic type.</param> /// <param name="assemblies">A list of assemblies that will be searched.</param> /// <param name="options">The options.</param> /// <returns>A collection of types.</returns> /// <exception cref="ArgumentNullException">Thrown when one of the arguments contain a null reference /// (Nothing in VB).</exception> public IEnumerable <Type> GetTypesToRegister(Type serviceType, IEnumerable <Assembly> assemblies, TypesToRegisterOptions options) { Requires.IsNotNull(serviceType, nameof(serviceType)); Requires.IsNotNull(assemblies, nameof(assemblies)); Requires.IsNotNull(options, nameof(options)); Requires.IsNotPartiallyClosed(serviceType, nameof(serviceType)); var types = from assembly in assemblies.Distinct() where !assembly.IsDynamic from type in GetTypesFromAssembly(assembly) where Types.IsConcreteType(type) where options.IncludeGenericTypeDefinitions || !type.IsGenericTypeDefinition() where Types.ServiceIsAssignableFromImplementation(serviceType, type) let ctor = this.SelectImplementationTypeConstructorOrNull(type) where ctor == null || options.IncludeDecorators || !Types.IsDecorator(serviceType, ctor) where ctor == null || options.IncludeComposites || !Types.IsComposite(serviceType, ctor) select type; return(types.ToArray()); }
/// <summary> /// Returns all concrete types that are located in the supplied <paramref name="assemblies"/> /// and implement or inherit from the supplied <typeparamref name="TService"/> and match the specified /// <paramref name="options."/>. /// </summary> /// <remarks> /// Use this method when you need influence the types that are registered using /// <see cref="Register(Type, IEnumerable{Assembly})">Register</see>. /// The <b>Register</b> overloads that take a collection of <see cref="Assembly"/> /// objects use this method internally to get the list of types that need to be registered. Instead of /// calling such overload, you can call an overload that takes a list of <see cref="Type"/> objects /// and pass in a filtered result from this <b>GetTypesToRegister</b> method. /// <code lang="cs"><![CDATA[ /// var container = new Container(); /// /// var assemblies = new[] { typeof(FileLogger).Assembly }; /// var options = new TypesToRegisterOptions { IncludeGenericTypeDefinitions: true }; /// var types = container.GetTypesToRegister<ILogger>(assemblies, options) /// .Where(t => t.IsPublic); /// /// container.Collection.Register<ILogger>(types); /// ]]></code> /// This example calls the <b>GetTypesToRegister</b> method to request a list of concrete implementations /// of the <b>ILogger</b> interface from the assembly of that interface. After that /// all internal types are filtered out. This list is supplied to the /// <see cref="ContainerCollectionRegistrator.Register{TService}(IEnumerable{Type})"> /// Collection.Register<TService>((IEnumerable<Type>)</see> overload to finish the /// registration. /// </remarks> /// <typeparam name="TService">The base type or interface to find derived types for.</typeparam> /// <param name="assemblies">A list of assemblies that will be searched.</param> /// <param name="options">The options.</param> /// <returns>A collection of types.</returns> /// <exception cref="ArgumentNullException">Thrown when one of the arguments contain a null reference. /// </exception> public IEnumerable <Type> GetTypesToRegister <TService>( IEnumerable <Assembly> assemblies, TypesToRegisterOptions options) { return(this.GetTypesToRegister(typeof(TService), assemblies, options)); }