private void RegisterInterfaces(Type component, SimpleInjector.Lifestyle lifestyle) { var registration = lifestyle.CreateRegistration(component, _container); var interfaces = component.GetInterfaces(); foreach (var serviceType in interfaces) { addRegistration(serviceType, registration); } }
public SimpleInjectorJobActivator(Injector.Container container, Injector.Lifestyle lifestyle) { if (container == null) { throw new ArgumentNullException("container"); } if (lifestyle == null) { throw new ArgumentNullException("lifestyle"); } _container = container; _lifestyle = lifestyle; }
public static void Configure(Container container, SimpleInjector.Lifestyle lifeStyle) { container.Register<IFileParserService, FileParserService>(lifeStyle); container.Register<IGridService, GridService>(lifeStyle); container.Register<IPositionService, PositionService>(lifeStyle); container.Register<IGameService, GameService>(lifeStyle); container.Register<IMoveFactory, MoveFactory>(lifeStyle); container.Register<ITurtleService, TurtleService>(lifeStyle); container.Collection.Register(typeof(IMoveService), new[] { typeof(MoveForwardService), typeof(MoveLeftService), typeof(MoveRightService) }); }
/// <summary> /// Ensures that the decorator type that is returned from <paramref name="decoratorTypeFactory"/> is /// supplied when the supplied <paramref name="predicate"/> returns <b>true</b> and cached with the given /// <paramref name="lifestyle"/>, wrapping the original registered <paramref name="serviceType"/>, by /// injecting that service type into the constructor of the decorator type that is returned by the /// supplied <paramref name="decoratorTypeFactory"/>. /// Multiple decorators may be applied to the same <paramref name="serviceType"/>. Decorators can be /// applied to both open, closed, and non-generic service types. /// </summary> /// <remarks> /// <para> /// The types returned from the <paramref name="decoratorTypeFactory"/> may be non-generic, /// closed-generic, open-generic and even partially-closed generic. The container will try to fill in /// the generic parameters based on the resolved service type. /// </para> /// <para> /// The <b>RegisterDecorator</b> method works by hooking onto the container's /// <see cref="Container.ExpressionBuilt">ExpressionBuilt</see> event. This event fires after the /// <see cref="Container.ResolveUnregisteredType">ResolveUnregisteredType</see> event, which allows /// decoration of types that are resolved using unregistered type resolution. /// </para> /// <para> /// Multiple decorators can be applied to the same service type. The order in which they are registered /// is the order they get applied in. This means that the decorator that gets registered first, gets /// applied first, which means that the next registered decorator, will wrap the first decorator, which /// wraps the original service type. /// </para> /// <para> /// Constructor injection will be used on that type, and although it may have many constructor /// arguments, it must have exactly one argument of the type of <paramref name="serviceType"/>, or an /// argument of type <see cref="Func{TResult}"/> where <b>TResult</b> is <paramref name="serviceType"/>. /// An exception will be thrown when this is not the case. /// </para> /// <para> /// The type returned from <paramref name="decoratorTypeFactory"/> may have a constructor with an /// argument of type <see cref="Func{T}"/> where <b>T</b> is <paramref name="serviceType"/>. In this /// case, the library will not inject the decorated <paramref name="serviceType"/> itself into the /// decorator instance, but it will inject a <see cref="Func{T}"/> that allows /// creating instances of the decorated type, according to the lifestyle of that type. This enables /// more advanced scenarios, such as executing the decorated types on a different thread, or executing /// decorated instance within a certain scope (such as a lifetime scope). /// </para> /// </remarks> /// <example> /// The following is an example of the registration of a decorator through the factory delegate: /// <code lang="cs"><![CDATA[ /// container.Register<ICommandHandler<MoveCustomerCommand>, MoveCustomerCommandHandler>(); /// /// container.RegisterDecorator( /// typeof(ICommandHandler<>), /// context => typeof(LoggingCommandHandler<,>).MakeGenericType( /// typeof(LoggingCommandHandler<,>).GetGenericArguments().First(), /// context.ImplementationType), /// Lifestyle.Transient, /// context => true); /// /// var handler = container.GetInstance<ICommandHandler<MoveCustomerCommand>>(); /// /// Assert.IsInstanceOfType(handler, /// typeof(LoggingCommandHandler<MoveCustomerCommand, MoveCustomerCommandHandler>)); /// /// ]]></code> /// The code above allows a generic <b>LoggingCommandHandler<TCommand, TImplementation></b> to /// be applied to command handlers, where the second generic argument will be filled in using the /// contextual information. /// </example> /// <param name="serviceType">The definition of the (possibly open generic) service type that will /// be wrapped by the decorator type that is returned from <paramref name="decoratorTypeFactory"/>.</param> /// <param name="decoratorTypeFactory">A factory that allows building Type objects that define the /// decorators to inject, based on the given contextual information. The delegate is allowed to return /// (partially) open-generic types.</param> /// <param name="lifestyle">The lifestyle that specifies how the returned decorator will be cached.</param> /// <param name="predicate">The predicate that determines whether the decorator must be applied to a /// service type.</param> /// <exception cref="ArgumentNullException">Thrown when one of the arguments is a null reference.</exception> public void RegisterDecorator(Type serviceType, Func <DecoratorPredicateContext, Type> decoratorTypeFactory, Lifestyle lifestyle, Predicate <DecoratorPredicateContext> predicate) { Requires.IsNotNull(serviceType, nameof(serviceType)); Requires.IsNotNull(decoratorTypeFactory, nameof(decoratorTypeFactory)); Requires.IsNotNull(lifestyle, nameof(lifestyle)); Requires.IsNotNull(predicate, nameof(predicate)); var interceptor = new DecoratorInterceptor( new DecoratorExpressionInterceptorData( this, serviceType, null, predicate, lifestyle, decoratorTypeFactory)); this.ExpressionBuilt += interceptor.ExpressionBuilt; }
/// <summary> /// Ensures that the supplied <paramref name="decoratorType"/> decorator is returned and cached with /// the given <paramref name="lifestyle"/>, wrapping the original registered /// <paramref name="serviceType"/>, by injecting that service type into the constructor of the /// supplied <paramref name="decoratorType"/>. Multiple decorators may be applied to the same /// <paramref name="serviceType"/>. Decorators can be applied to both open, closed, and non-generic /// service types. /// </summary> /// <remarks> /// <para> /// The <b>RegisterDecorator</b> method works by hooking onto the container's /// <see cref="Container.ExpressionBuilt">ExpressionBuilt</see> event. This event fires after the /// <see cref="Container.ResolveUnregisteredType">ResolveUnregisteredType</see> event, which allows /// decoration of types that are resolved using unregistered type resolution. /// </para> /// <para> /// Multiple decorators can be applied to the same service type. The order in which they are registered /// is the order they get registered. This means that the decorator that gets registered first, gets /// applied first, which means that the next registered decorator, will wrap the first decorator, which /// wraps the original service type. /// </para> /// <para> /// Constructor injection will be used on that type, and although it may have many constructor /// arguments, it must have exactly one argument of the type of <paramref name="serviceType"/>, or an /// argument of type <see cref="Func{TResult}"/> where <b>TResult</b> is <paramref name="serviceType"/>. /// An exception will be thrown when this is not the case. /// </para> /// <para> /// The registered <paramref name="decoratorType"/> may have a constructor with an argument of type /// <see cref="Func{T}"/> where <b>T</b> is <paramref name="serviceType"/>. In this case, the /// will not inject the decorated <paramref name="serviceType"/> itself into the /// <paramref name="decoratorType"/> instance, but it will inject a <see cref="Func{T}"/> that allows /// creating instances of the decorated type, according to the lifestyle of that type. This enables /// more advanced scenarios, such as executing the decorated types on a different thread, or executing /// decorated instance within a certain scope (such as a lifetime scope). /// </para> /// </remarks> /// <example> /// Please see the <see cref="RegisterDecorator(Type, Type)">RegisterDecorator</see> method /// for more information. /// </example> /// <param name="serviceType">The definition of the (possibly open generic) service type that will /// be wrapped by the given <paramref name="decoratorType"/>.</param> /// <param name="decoratorType">The definition of the (possibly open generic) decorator type that will /// be used to wrap the original service type.</param> /// <param name="lifestyle">The lifestyle that specifies how the returned decorator will be cached.</param> /// <exception cref="ArgumentNullException">Thrown when one of the arguments is a null reference.</exception> /// <exception cref="ArgumentException">Thrown when <paramref name="serviceType"/> is not /// an open generic type, when <paramref name="decoratorType"/> does not inherit from or /// implement <paramref name="serviceType"/>, when <paramref name="decoratorType"/> /// does not have a single public constructor, or when <paramref name="decoratorType"/> does /// not contain a constructor that has exactly one argument of type /// <paramref name="serviceType"/> or <see cref="Func{T}"/> where <b>T</b> is /// <paramref name="serviceType"/>.</exception> public void RegisterDecorator(Type serviceType, Type decoratorType, Lifestyle lifestyle) { this.RegisterDecoratorCore(serviceType, decoratorType, lifestyle: lifestyle); }
/// <summary> /// Ensures that the supplied <typeparamref name="TDecorator"/> decorator is returned and cached with /// the given <paramref name="lifestyle"/>, wrapping the original registered /// <typeparamref name="TService"/>, by injecting that service type into the constructor of the /// supplied <typeparamref name="TDecorator"/>. Multiple decorators may be applied to the same /// <typeparamref name="TService"/>. Decorators can be applied to both open, closed, and non-generic /// service types. /// </summary> /// <remarks> /// <para> /// The <b>RegisterDecorator</b> method works by hooking onto the container's /// <see cref="Container.ExpressionBuilt">ExpressionBuilt</see> event. This event fires after the /// <see cref="Container.ResolveUnregisteredType">ResolveUnregisteredType</see> event, which allows /// decoration of types that are resolved using unregistered type resolution. /// </para> /// <para> /// Multiple decorators can be applied to the same service type. The order in which they are registered /// is the order they get registered. This means that the decorator that gets registered first, gets /// applied first, which means that the next registered decorator, will wrap the first decorator, which /// wraps the original service type. /// </para> /// <para> /// Constructor injection will be used on that type, and although it may have many constructor /// arguments, it must have exactly one argument of the type of <typeparamref name="TService"/>, or an /// argument of type <see cref="Func{TResult}"/> where <b>TResult</b> is <typeparamref name="TService"/>. /// An exception will be thrown when this is not the case. /// </para> /// <para> /// The registered <typeparamref name="TDecorator"/> may have a constructor with an argument of type /// <see cref="Func{T}"/> where <b>T</b> is <typeparamref name="TService"/>. In this case, the /// will not inject the decorated <typeparamref name="TService"/> itself into the /// <typeparamref name="TDecorator"/> instance, but it will inject a <see cref="Func{T}"/> that allows /// creating instances of the decorated type, according to the lifestyle of that type. This enables /// more advanced scenarios, such as executing the decorated types on a different thread, or executing /// decorated instance within a certain scope (such as a lifetime scope). /// </para> /// </remarks> /// <example> /// Please see <see cref="RegisterDecorator(Type, Type)"/> for an example. /// </example> /// <typeparam name="TService">The service type that will be wrapped by the given /// <typeparamref name="TDecorator"/>.</typeparam> /// <typeparam name="TDecorator">The decorator type that will be used to wrap the original service type.</typeparam> /// <param name="lifestyle">The lifestyle that specifies how the returned decorator will be cached.</param> /// <exception cref="ArgumentNullException">Thrown when one of the arguments is a null reference.</exception> /// <exception cref="ArgumentException">Thrown when <typeparamref name="TDecorator"/> /// does not have a single public constructor, or when <typeparamref name="TDecorator"/> does /// not contain a constructor that has exactly one argument of type /// <typeparamref name="TService"/> or <see cref="Func{T}"/> where <b>T</b> is /// <typeparamref name="TService"/>.</exception> public void RegisterDecorator <TService, TDecorator>(Lifestyle lifestyle) { this.RegisterDecoratorCore(typeof(TService), typeof(TDecorator), lifestyle: lifestyle); }
private static IServiceProvider GetServiceProviderForBackgroundThread(Container container, Lifestyle lifestyle) => Lifestyle.Scoped.GetCurrentScope(container) != null ? container.GetInstance <IServiceScope>().ServiceProvider : throw new ActivationException( $"You are trying to resolve a {lifestyle.Name} cross-wired service, but are doing so outside the context " + $"of a web request. To be able to resolve this service, the operation must run in the context of an " + $"active ({container.Options.DefaultScopedLifestyle.Name}) scope.");
/// <summary> /// Registers all concrete, non-generic, public and internal types in the given set of /// <paramref name="assemblies"/> that implement the given <paramref name="openGenericServiceType"/> /// with the supplied <paramref name="lifestyle"/>. /// <see cref="TypesToRegisterOptions.IncludeDecorators">Decorators</see> and /// <see cref="TypesToRegisterOptions.IncludeGenericTypeDefinitions">generic type definitions</see> /// will be excluded from registration, while /// <see cref="TypesToRegisterOptions.IncludeComposites">composites</see> are included. /// </summary> /// <param name="openGenericServiceType">The definition of the open generic type.</param> /// <param name="assemblies">A list of assemblies that will be searched.</param> /// <param name="lifestyle">The lifestyle to register instances with.</param> /// <exception cref="ArgumentNullException">Thrown when one of the arguments contain a null /// reference (Nothing in VB).</exception> /// <exception cref="ArgumentException">Thrown when <paramref name="openGenericServiceType"/> is not /// an open generic type.</exception> /// <exception cref="InvalidOperationException">Thrown when the given set of /// <paramref name="assemblies"/> contain multiple types that implement the same /// closed generic version of the given <paramref name="openGenericServiceType"/>.</exception> public void Register(Type openGenericServiceType, IEnumerable <Assembly> assemblies, Lifestyle lifestyle) { Requires.IsNotNull(openGenericServiceType, nameof(openGenericServiceType)); Requires.IsNotNull(lifestyle, nameof(lifestyle)); Requires.IsNotNull(assemblies, nameof(assemblies)); Requires.IsGenericType(openGenericServiceType, nameof(openGenericServiceType), guidance: StringResources.SuppliedTypeIsNotGenericExplainingAlternativesWithAssemblies); Requires.IsNotPartiallyClosed(openGenericServiceType, nameof(openGenericServiceType)); Requires.IsOpenGenericType(openGenericServiceType, nameof(openGenericServiceType), guidance: StringResources.SuppliedTypeIsNotOpenGenericExplainingAlternativesWithAssemblies); Type[] skippedDecorators; Type[] implementationTypes = this.GetNonGenericTypesToRegisterForOneToOneMapping( openGenericServiceType, assemblies, out skippedDecorators); this.Register(openGenericServiceType, implementationTypes, lifestyle); this.AddSkippedDecorators(openGenericServiceType, skippedDecorators); }
/// <summary> /// Registers all supplied <paramref name="implementationTypes"/> based on the closed-generic version /// of the given <paramref name="openGenericServiceType"/> with the given <paramref name="lifestyle"/>. /// </summary> /// <param name="openGenericServiceType">The definition of the open generic type.</param> /// <param name="implementationTypes">A list types to be registered.</param> /// <param name="lifestyle">The lifestyle to register instances with.</param> /// <exception cref="ArgumentNullException">Thrown when one of the arguments contain a null /// reference (Nothing in VB).</exception> /// <exception cref="ArgumentException">Thrown when <paramref name="openGenericServiceType"/> is not /// an open generic type or when one of the supplied types from the /// <paramref name="implementationTypes"/> collection does not derive from /// <paramref name="openGenericServiceType"/>.</exception> /// <exception cref="InvalidOperationException">Thrown when the given set of /// <paramref name="implementationTypes"/> contain multiple types that implement the same /// closed generic version of the given <paramref name="openGenericServiceType"/>.</exception> public void Register(Type openGenericServiceType, IEnumerable <Type> implementationTypes, Lifestyle lifestyle) { Requires.IsNotNull(openGenericServiceType, nameof(openGenericServiceType)); Requires.IsNotNull(lifestyle, nameof(lifestyle)); Requires.IsNotNull(implementationTypes, nameof(implementationTypes)); Requires.IsGenericType(openGenericServiceType, nameof(openGenericServiceType), guidance: StringResources.SuppliedTypeIsNotGenericExplainingAlternativesWithTypes); Requires.IsNotPartiallyClosed(openGenericServiceType, nameof(openGenericServiceType)); Requires.IsOpenGenericType(openGenericServiceType, nameof(openGenericServiceType), guidance: StringResources.SuppliedTypeIsNotOpenGenericExplainingAlternativesWithTypes); implementationTypes = implementationTypes.Distinct().ToArray(); Requires.DoesNotContainNullValues(implementationTypes, nameof(implementationTypes)); Requires.CollectionDoesNotContainOpenGenericTypes(implementationTypes, nameof(implementationTypes)); Requires.ServiceIsAssignableFromImplementations(openGenericServiceType, implementationTypes, nameof(implementationTypes), typeCanBeServiceType: false); var mappings = from mapping in BatchMapping.Build(openGenericServiceType, implementationTypes) let registration = lifestyle.CreateRegistration(mapping.ImplementationType, this) from serviceType in mapping.ClosedServiceTypes select new { serviceType, registration }; foreach (var mapping in mappings) { this.AddRegistration(mapping.serviceType, mapping.registration); } }
public static void RegisterEventHandlersFromAssemblyOf <T>(this Container container, Lifestyle lifestyle) { var assembly = typeof(T).GetTypeInfo().Assembly; RegisterEventHandlersFromAssembly(container, assembly, lifestyle); }
/// <summary> /// Ensures that the supplied <typeparamref name="TDecorator"/> decorator is returned and cached with /// the given <paramref name="lifestyle"/>, wrapping the original registered /// <typeparamref name="TService"/>, by injecting that service type into the constructor of the /// supplied <typeparamref name="TDecorator"/>. Multiple decorators may be applied to the same /// <typeparamref name="TService"/>. Decorators can be applied to both open, closed, and non-generic /// service types. /// </summary> /// <remarks> /// <para> /// The <b>RegisterDecorator</b> method works by hooking onto the container's /// <see cref="Container.ExpressionBuilt">ExpressionBuilt</see> event. This event fires after the /// <see cref="Container.ResolveUnregisteredType">ResolveUnregisteredType</see> event, which allows /// decoration of types that are resolved using unregistered type resolution. /// </para> /// <para> /// Multiple decorators can be applied to the same service type. The order in which they are registered /// is the order they get registered. This means that the decorator that gets registered first, gets /// applied first, which means that the next registered decorator, will wrap the first decorator, which /// wraps the original service type. /// </para> /// <para> /// Constructor injection will be used on that type, and although it may have many constructor /// arguments, it must have exactly one argument of the type of <typeparamref name="TService"/>, or an /// argument of type <see cref="Func{TResult}"/> where <b>TResult</b> is <typeparamref name="TService"/>. /// An exception will be thrown when this is not the case. /// </para> /// <para> /// The registered <typeparamref name="TDecorator"/> may have a constructor with an argument of type /// <see cref="Func{T}"/> where <b>T</b> is <typeparamref name="TService"/>. In this case, the /// will not inject the decorated <typeparamref name="TService"/> itself into the /// <typeparamref name="TDecorator"/> instance, but it will inject a <see cref="Func{T}"/> that allows /// creating instances of the decorated type, according to the lifestyle of that type. This enables /// more advanced scenarios, such as executing the decorated types on a different thread, or executing /// decorated instance within a certain scope (such as a lifetime scope). /// </para> /// </remarks> /// <example> /// Please see <see cref="RegisterDecorator(Type, Type)"/> for an example. /// </example> /// <typeparam name="TService">The service type that will be wrapped by the given /// <typeparamref name="TDecorator"/>.</typeparam> /// <typeparam name="TDecorator">The decorator type that will be used to wrap the original service type.</typeparam> /// <param name="lifestyle">The lifestyle that specifies how the returned decorator will be cached.</param> /// <exception cref="ArgumentNullException">Thrown when one of the arguments is a null reference.</exception> /// <exception cref="ArgumentException">Thrown when <typeparamref name="TDecorator"/> /// does not have a single public constructor, or when <typeparamref name="TDecorator"/> does /// not contain a constructor that has exactly one argument of type /// <typeparamref name="TService"/> or <see cref="Func{T}"/> where <b>T</b> is /// <typeparamref name="TService"/>.</exception> public void RegisterDecorator <TService, TDecorator>(Lifestyle lifestyle) where TService : class where TDecorator : class, TService { this.RegisterDecoratorCore(typeof(TService), typeof(TDecorator), lifestyle: lifestyle); }
private static IServiceProvider GetServiceProviderForBackgroundThread( Container container, Lifestyle lifestyle) => Lifestyle.Scoped.GetCurrentScope(container) != null ? container.GetInstance <IServiceScope>().ServiceProvider : throw new ActivationException(
public static void RegisterCommandHandlersFromAssembly(this Container container, Assembly assembly, Lifestyle lifestyle) { if (lifestyle == null) { throw new ArgumentNullException(nameof(lifestyle)); } var types = assembly.DefinedTypes.Where(x => x.IsClass && !x.IsAbstract && !x.IsGenericType && ( x.IsAssignableToGenericType(typeof(ICommandHandler <>)) || x.IsAssignableToGenericType(typeof(ICommandHandler <,>)) || x.IsAssignableToGenericType(typeof(IAsyncCommandHandler <>)) || x.IsAssignableToGenericType(typeof(IAsyncCommandHandler <,>)) )); foreach (var o in types.Select(t => new { Implementation = t, Services = t.ImplementedInterfaces })) { var type = o.Implementation.AsType(); var attr = o.Implementation.GetCustomAttribute <LifetimeAttribute>(); var registration = (attr?.Lifestyle ?? lifestyle).CreateRegistration(type, container); container.AddRegistration(type, registration); foreach (var serviceType in o.Services) { container.AddRegistration(serviceType, registration); } } }
public static void RegisterCommandHandlersFromAssemblyOf <T>(this Container container, Lifestyle lifestyle) { RegisterCommandHandlersFromAssembly(container, typeof(T).GetTypeInfo().Assembly, lifestyle); }
public static void RegisterCqrsFromAssemblyOf <T>(this Container container, Lifestyle lifestyle) { RegisterCommandHandlersFromAssemblyOf <T>(container, lifestyle); RegisterQueryHandlersFromAssemblyOf <T>(container, lifestyle); RegisterEventHandlersFromAssemblyOf <T>(container, lifestyle); }
private void RegisterDecoratorCore(Type serviceType, Type decoratorType, Predicate <DecoratorPredicateContext> predicate = null, Lifestyle lifestyle = null) { Requires.IsNotNull(serviceType, nameof(serviceType)); Requires.IsNotNull(decoratorType, nameof(decoratorType)); Requires.ServiceTypeIsNotClosedWhenImplementationIsOpen(serviceType, decoratorType); Requires.ServiceOrItsGenericTypeDefinitionIsAssignableFromImplementation(serviceType, decoratorType, nameof(serviceType)); Requires.ImplementationHasSelectableConstructor(this, serviceType, decoratorType, nameof(decoratorType)); Requires.IsDecorator(this, serviceType, decoratorType, nameof(decoratorType)); Requires.DecoratorIsNotAnOpenGenericTypeDefinitionWhenTheServiceTypeIsNot(serviceType, decoratorType, nameof(decoratorType)); Requires.OpenGenericTypeDoesNotContainUnresolvableTypeArguments(serviceType, decoratorType, nameof(decoratorType)); var interceptor = new DecoratorInterceptor( new DecoratorExpressionInterceptorData( this, serviceType, decoratorType, predicate, lifestyle ?? this.SelectionBasedLifestyle)); this.ExpressionBuilt += interceptor.ExpressionBuilt; }
/// <summary> /// Allows registrations made using the <see cref="IServiceCollection"/> API to be resolved by Simple Injector. /// </summary> /// <param name="container">The container.</param> /// <param name="app">The <see cref="IApplicationBuilder"/> instance.</param> public static void AutoCrossWireAspNetComponents(this Container container, IApplicationBuilder app) { if (container == null) { throw new ArgumentNullException(nameof(container)); } if (app == null) { throw new ArgumentNullException(nameof(app)); } var services = (IServiceCollection)container.GetItem(CrossWireContextKey); if (services == null) { throw new InvalidOperationException( "To use this method, please make sure cross-wiring is enabled, by invoking " + $"the {nameof(EnableSimpleInjectorCrossWiring)} extension method as part of the " + "ConfigureServices method of the Startup class. " + "See https://simpleinjector.org/aspnetcore for more information."); } if (container.Options.DefaultScopedLifestyle == null) { throw new InvalidOperationException( "To be able to allow auto cross-wiring, please ensure that the container is configured with a " + "default scoped lifestyle by setting the Container.Options.DefaultScopedLifestyle property " + "with the required scoped lifestyle for your type of application. In ASP.NET Core, the typical " + $"lifestyle to use is the {nameof(AsyncScopedLifestyle)}. " + "See: https://simpleinjector.org/lifestyles#scoped"); } CrossWireServiceScope(container, app); IHttpContextAccessor accessor = GetHttpContextAccessor(app); container.ResolveUnregisteredType += (s, e) => { if (e.Handled) { return; } Type serviceType = e.UnregisteredServiceType; ServiceDescriptor descriptor = FindServiceDescriptor(services, serviceType); if (descriptor != null) { Lifestyle lifestyle = ToLifestyle(descriptor.Lifetime); // Create a cross-wire registration that calls back into the .NET Core container. Registration registration = lifestyle.CreateRegistration(serviceType, () => GetServiceProvider(accessor, container).GetRequiredService(serviceType), container); // Apply the required suppressions. if (lifestyle == Lifestyle.Transient && typeof(IDisposable).IsAssignableFrom(serviceType)) { registration.SuppressDiagnosticWarning( DiagnosticType.DisposableTransientComponent, justification: "This is a cross-wired service. ASP.NET will ensure it gets disposed."); } e.Register(registration); } }; }
/// <summary> /// Registers all concrete, non-generic, public and internal types in the given set of /// <paramref name="assemblies"/> that implement the given <paramref name="openGenericServiceType"/> /// with the supplied <paramref name="lifestyle"/>. /// </summary> /// <param name="openGenericServiceType">The definition of the open generic type.</param> /// <param name="assemblies">A list of assemblies that will be searched.</param> /// <param name="lifestyle">The lifestyle to register instances with.</param> /// <exception cref="ArgumentNullException">Thrown when one of the arguments contain a null /// reference (Nothing in VB).</exception> /// <exception cref="ArgumentException">Thrown when <paramref name="openGenericServiceType"/> is not /// an open generic type.</exception> /// <exception cref="InvalidOperationException">Thrown when the given set of /// <paramref name="assemblies"/> contain multiple types that implement the same /// closed generic version of the given <paramref name="openGenericServiceType"/>.</exception> public void Register(Type openGenericServiceType, IEnumerable <Assembly> assemblies, Lifestyle lifestyle) { Requires.IsNotNull(openGenericServiceType, nameof(openGenericServiceType)); Requires.IsNotNull(lifestyle, nameof(lifestyle)); Requires.IsNotNull(assemblies, nameof(assemblies)); Requires.IsGenericType(openGenericServiceType, nameof(openGenericServiceType), guidance: StringResources.SuppliedTypeIsNotGenericExplainingAlternativesWithAssemblies); Requires.IsNotPartiallyClosed(openGenericServiceType, nameof(openGenericServiceType)); Requires.IsOpenGenericType(openGenericServiceType, nameof(openGenericServiceType), guidance: StringResources.SuppliedTypeIsNotOpenGenericExplainingAlternativesWithAssemblies); var implementationTypes = this.GetTypesToRegister(openGenericServiceType, assemblies); this.Register(openGenericServiceType, implementationTypes, lifestyle); }