public static void ConfigContainer(Container container)
        {
            #region - MAPPER -
            var mapperConfig = AutoMapperConfig.GetMapperConfiguration();
            container.RegisterSingleton<IConfigurationProvider>(mapperConfig);
            container.Register(() => mapperConfig.CreateMapper());
            container.Register<IMapperAdapter, AutoMapperAdapter>();
            #endregion

            #region - CONTEXTS -
            container.Register<DbContext, CoreContext>(Lifestyle.Scoped);
            #endregion

            #region - REPOSITORIES -
            container.Register<IClientRepository, ClientRepository>(Lifestyle.Scoped);
            container.Register<IRefreshTokenRepository, RefreshTokenRepository>(Lifestyle.Scoped);
            container.Register<IUsuarioRepository, UsuarioRepository>(Lifestyle.Scoped);
            #endregion

            #region - DOMAINS -
            var registration = Lifestyle.Scoped.CreateRegistration<UsuarioDomain>(container);
            container.AddRegistration(typeof(IUsuarioDomain), registration);
            container.AddRegistration(typeof(IUserStore<Usuario, long>), registration);

            container.Register<UserManager<Usuario, long>>(Lifestyle.Scoped);
            container.Register<IRefreshTokenDomain, RefreshTokenDomain>(Lifestyle.Scoped);
            container.Register<IClientDomain, ClientDomain>(Lifestyle.Scoped);
            container.Register<IAccountDomain, AccountDomain>(Lifestyle.Scoped);
            #endregion
        }
        public void RegisterServices(Container container)
        {
            // Required: How to instantiate the DbContext; and share it amongst objects participating in a single request.
            var webApiRequestLifestyle = new WebApiRequestLifestyle(true);
            var hybridLifestyle = Lifestyle.CreateHybrid(() => webApiRequestLifestyle.GetCurrentScope(container) == null, Lifestyle.Transient, webApiRequestLifestyle);
            container.Register(() =>
                               {
                                   var db = new ScrumDb();
                                   db.AttachDbEnums();
                                   return db;
                               },
                               hybridLifestyle);
            container.RegisterLazy<ScrumDb>();

            // Required: Register global datamodel metadata
            var metadataRegistration = hybridLifestyle.CreateRegistration<DbContextMetadata<ScrumDb>>(container);
            container.AddRegistration(typeof(IContainerMetadata<ScrumDb>), metadataRegistration);
            container.AddRegistration(typeof(IContainerMetadata), metadataRegistration);

            // Query validation settings could be specified here
            //container.RegisterInstance(new ODataValidationSettings
            //{
            //	MaxExpansionDepth = 15,
            //	MaxTop = 200
            //}); //.Named<ODataValidationSettings>("Edit");  TODO: Figure out how to separate ODataValidationSettings for Edit controllers vs ReadOnly controllers
        }
Example #3
0
        /// <inheritdoc />
        public void RegisterServices(Container container)
        {
            var registration = Lifestyle.Singleton.CreateRegistration <Mediators.Mediator>(container);

            container.AddRegistration <IMediator>(registration);
            container.AddRegistration <IMessageRecipientsRegistrar>(registration);
            container.AddRegistration <IPipelineProcessorsRegistrar>(registration);

            container.Register <IPreProcessorService, PreProcessorService>(Lifestyle.Singleton);
            container.Register <IEventCollectorFactory, EventCollectorFactory>(Lifestyle.Singleton);
            container.Collection.Register <IMessageHandler>(GetType().Assembly);
            container.Collection.Register <IMessageHandlerAsync>(GetType().Assembly);

            container.Register <MediatorRegistrar>(Lifestyle.Singleton);
        }
Example #4
0
        public void Configuration(IAppBuilder app)
        {
            var container = new Container();

            var registration = Lifestyle.Transient.CreateRegistration
            (
                typeof(ChatHub),
                () => new ChatHub(new ChatService()),
                container
            );

            container.AddRegistration(typeof(ChatHub), registration);
            registration.SuppressDiagnosticWarning
            (
                DiagnosticType.DisposableTransientComponent,
                "Ignoring IDisposable for transient hubs"
            );

            container.Verify();

            var config = new HubConfiguration()
            {
                Resolver = new ChatHubDependencyResolver(container)
            };

            app.MapSignalR(config);
        }
Example #5
0
		/// <summary>
		/// Registers application-level IoC settings.
		/// </summary>
		/// <param name="container"></param>
		public void RegisterServices(Container container)
		{
			container.RegisterWebApiRequestOrTransient<TodoListContext>();
			container.RegisterLazy<TodoListContext>();

			// Required: Register global datamodel metadata (IContainerMetadata and IContainerMetadata<DbContext>)
			var mmRegistration = Lifestyle.Singleton.CreateRegistration(() => new DbContextMetadata<TodoListContext>(new TodoListContext()), container);
			container.AddRegistration(typeof(IContainerMetadata), mmRegistration);
			container.AddRegistration(typeof(IContainerMetadata<TodoListContext>), mmRegistration);
			
			// Query validation settings could be specified here
			container.RegisterSingleton(new ODataValidationSettings()
			{
				MaxExpansionDepth = 5
			});
		}
        public void RegisterServices(Container container)
        {
            var serviceAssemblies = new[]
            {
                typeof(IService).Assembly,
                Assembly.Load(AssemblyConstants.ServicesData),
                Assembly.Load(AssemblyConstants.ServicesAdministration),
            };

            var registrations = serviceAssemblies
                .SelectMany(a => a.GetExportedTypes())
                .Where(t => typeof(IService).IsAssignableFrom(t) && !t.IsAbstract && !t.IsGenericTypeDefinition)
                .Select(t => new { Service = t.GetInterfaces().Single(i => i != typeof(IService)), Implementation = t })
                .ToList();

            var webRequestLifestyle = new WebRequestLifestyle();
            foreach (var registration in registrations)
            {
                container.AddRegistration(
                    registration.Service,
                    webRequestLifestyle.CreateRegistration(registration.Service, registration.Implementation, container));
            }

            //// TODO: Register with LINQ!

            ////container.Register<ICacheService, HttpRuntimeCacheService>(webRequestLifestyle);
            ////container.Register<ICacheItemsProviderService, CacheItemsProviderService>(webRequestLifestyle);
            ////container.Register<ITagsDataService, TagsDataService>(webRequestLifestyle);
            ////container.Register<IPostsDataService, PostsDataService>(webRequestLifestyle);
            ////container.Register<ICommentsDataService, CommentsDataService>(webRequestLifestyle);
        }
Example #7
0
		public void RegisterServices(Container container)
		{
			container.RegisterWebApiRequestOrTransient<EStoreDb>();
			container.RegisterLazy<EStoreDb>();

			// Required: Register global datamodel metadata
			var mmRegistration = Lifestyle.Singleton.CreateRegistration<DbContextMetadata<EStoreDb>>(container);
			container.AddRegistration(typeof(IContainerMetadata), mmRegistration);
			container.AddRegistration(typeof(IContainerMetadata<EStoreDb>), mmRegistration);

			// Query validation settings could be specified here
			container.RegisterSingleton(new ODataValidationSettings()
			                            {
				                            MaxExpansionDepth = 5,
				                            MaxTop = 200
			                            });
		}
Example #8
0
        public static void Setup()
        {
            var container = new Container();
            var perRequest = new WebRequestLifestyle();
            var dataAccessAssembly = typeof(CinemaContext).Assembly;
            var moviesAssembly = typeof(Seat).Assembly;
            var promotionsAssembly = typeof(Promotions.Promotion).Assembly;
            var applicationAssembly = typeof(RenamePromotionCommand).Assembly;
            var connectionString = ConfigurationManager.ConnectionStrings["DDDCinema"].ConnectionString;

            container.Register(() => new CinemaContext(connectionString), perRequest);
            container.Register(() => new PromotionsContext(connectionString), perRequest);
            container.Register(() => new InfrastructureContext(connectionString), perRequest);
            container.Register(() => new DDDCinemaReadonly(), perRequest);
            var userProviderRegistration = Lifestyle.Singleton.CreateRegistration<ContextUserProvider>(container);
            container.AddRegistration(typeof(ICurrentUserProvider), userProviderRegistration);
            container.AddRegistration(typeof(ContextUserProvider), userProviderRegistration);
            container.Register<IWinChanceCalculatorFactory, SimpleInjectorWinChanceCalculatorFactory>(Lifestyle.Singleton);

            foreach (var repositorType in dataAccessAssembly.GetExportedTypes()
                .Where(t => t.Name.Contains("Repository")))
            {
                container.Register(repositorType.GetInterfaces().Single(), repositorType, perRequest);
            }

            container.RegisterDecorator(typeof(ICommandHandler<LoginCommand>), typeof(AuditingLoginCommandHandler));
            container.RegisterDecorator(typeof(ICommandHandler<>), typeof(AuditingCommandHandler<>),
                p => !p.AppliedDecorators.Any(t => t.Name.Contains("Auditing")));
            container.RegisterDecorator(typeof(ICommandHandler<>), typeof(CinemaTransactionalCommandHandler<>));
            container.RegisterDecorator(typeof(ICommandHandler<>), typeof(PromotionTransactionalCommandHandler<>));
            container.RegisterDecorator(typeof(ICommandHandler<>), typeof(InfrastructureTransactionalCommandHandler<>));
            container.Register(typeof(ICommandHandler<>), new[] { applicationAssembly });

            container.RegisterCollection(typeof(INotificationSender), new[] { moviesAssembly });
            var registration = perRequest.CreateRegistration<SendNotificationWhenSeatTaken>(container);
            container.AppendToCollection(typeof(IDomainEventHandler<>), typeof(AuditOccurrenceEventHandler<>));
            container.RegisterCollection(typeof(IDomainEventHandler<>), moviesAssembly, promotionsAssembly);
            container.RegisterDecorator(typeof(IDomainEventHandler<>), typeof(AuditingEventHandler<>),
                p => !p.ImplementationType.Name.Contains("Audit"));

            container.Register<List<INotificationSender>>(() => container.GetAllInstances<INotificationSender>().ToList(), perRequest);
            container.Register<ISheduler, SagaTimeoutSheduler>(perRequest);
            container.Register<IPromotionCodeGenerator, PromoCodeGenerator>(perRequest);
            DomainEventBus.Current = new SimpleInjectorEventBus(container);
            DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
        }
Example #9
0
		/// <summary>
		/// Registers application-level IoC settings.
		/// </summary>
		/// <param name="container"></param>
		public void RegisterServices(Container container)
		{
			container.RegisterWebApiRequestOrTransient<ScrumDb>();
			container.RegisterLazy<ScrumDb>();

			// Required: Register global datamodel metadata (IContainerMetadata and IContainerMetadata<DbContext>)
			var mmRegistration = Lifestyle.Singleton.CreateRegistration(() => new DbContextMetadata<ScrumDb>(new ScrumDb()), container);
			container.AddRegistration(typeof(IContainerMetadata), mmRegistration);
			container.AddRegistration(typeof(IContainerMetadata<ScrumDb>), mmRegistration);

			// Query validation settings could be specified here
			container.RegisterSingleton(new ODataValidationSettings()
			                            {
				                            MaxExpansionDepth = 5,
				                            MaxTop = 200
			                            }); //.Named<ODataValidationSettings>("Edit");  TODO: Figure out how to separate ODataValidationSettings for Edit controllers vs ReadOnly controllers
		}
Example #10
0
        public static void RegisterWindowsForm(this SimpleInjector.Container container, Type viewType, Type formType)
        {
            var producer = SimpleInjector.Lifestyle.Transient.CreateProducer(viewType, formType, container);

            producer.Registration.SuppressDiagnosticWarning(
                SimpleInjector.Diagnostics.DiagnosticType.DisposableTransientComponent,
                "Forms should be disposed by app code; not by the container.");

            container.AddRegistration(viewType, producer.Registration);
        }
Example #11
0
        public static void RegisterQueryHandlersFromAssembly(this Container container, Assembly assembly)
        {
            var types = assembly.DefinedTypes.Where(x => x.IsClass && !x.IsAbstract && !x.IsGenericType &&
                                                    (
                                                        x.IsAssignableToGenericType(typeof(IQueryHandler <,>)) ||
                                                        x.IsAssignableToGenericType(typeof(IAsyncQueryHandler <,>))
                                                    ));

            foreach (var o in types.Select(t => new { Implementation = t, Services = t.ImplementedInterfaces }))
            {
                var type = o.Implementation.AsType();
                var attr = o.Implementation.GetCustomAttribute <LifetimeAttribute>() ?? new LifetimeAttribute(Lifetime.Transient);

                Registration registration;

                switch (attr.Lifetime)
                {
                case Lifetime.Singleton:
                    registration = Lifestyle.Singleton.CreateRegistration(type, container);
                    break;

                case Lifetime.Scoped:
                    registration = Lifestyle.Scoped.CreateRegistration(type, container);
                    break;

                case Lifetime.Transient:
                    registration = Lifestyle.Transient.CreateRegistration(type, container);
                    break;

                default:
                    throw new CoreSharpException($"Invalid {nameof(Lifetime)} value: {attr.Lifetime}");
                }

                container.AddRegistration(type, registration);

                foreach (var serviceType in o.Services)
                {
                    container.AddRegistration(serviceType, registration);
                }
            }
        }
Example #12
0
		/// <summary>
		/// Registers application-level IoC settings.
		/// </summary>
		/// <param name="container"></param>
		public void RegisterServices(Container container)
		{
			// Support sharing the DbContext amongst objects participating in a single request;
			// but if there is no request, just make it transient.
			var webApiRequestLifestyle = new WebApiRequestLifestyle(true);
			var hybridLifestyle = Lifestyle.CreateHybrid(() => webApiRequestLifestyle.GetCurrentScope(container) == null, Lifestyle.Transient, webApiRequestLifestyle);
			container.Register<TodoListContext>(hybridLifestyle);
			container.RegisterLazy<TodoListContext>();

			// Required: Register global datamodel metadata (IContainerMetadata and IContainerMetadata<DbContext>)
			var mmRegistration = Lifestyle.Singleton.CreateRegistration<DbContextMetadata<TodoListContext>>(container);
			container.AddRegistration(typeof(IContainerMetadata), mmRegistration);
			container.AddRegistration(typeof(IContainerMetadata<TodoListContext>), mmRegistration);

			// Query validation settings could be specified here
			container.RegisterSingle(new ODataValidationSettings()
			{
				MaxExpansionDepth = 5,
				MaxTop = 200
			});
		}
        /// <summary>
        /// Cross-wires an ASP.NET Core or third party service to the container, to allow the service to be
        /// injected into components that are built by the container.
        /// </summary>
        /// <param name="container">The container.</param>
        /// <param name="serviceType">The type of service object to ross-wire.</param>
        /// <param name="builder">The IApplicationBuilder to retrieve the service object from.</param>
        public static void CrossWire(this Container container, Type serviceType, IApplicationBuilder builder)
        {
            Requires.IsNotNull(container, nameof(container));
            Requires.IsNotNull(serviceType, nameof(serviceType));
            Requires.IsNotNull(builder, nameof(builder));

            CrossWireServiceScope(container, builder.GetApplicationServices());

            Registration registration = CreateCrossWireRegistration(container, serviceType, builder.GetApplicationServices());

            container.AddRegistration(serviceType, registration);
        }
        public static void RegisterMvcControllers(this Container container, params Assembly[] assemblies)
        {
            foreach (Type controllerType in GetControllerTypesToRegister(container, assemblies))
            {
                Registration registration = Lifestyle.Transient.CreateRegistration(controllerType, container);

                registration.SuppressDiagnosticWarning(DiagnosticType.DisposableTransientComponent,
                                                       justification:
                                                       "MVC's DefaultControllerFactory disposes the controller when the web request ends.");

                container.AddRegistration(controllerType, registration);
            }
        }
Example #15
0
        public static void RegisterMvcControllers(this Container container, params Assembly[] assemblies)
        {
            foreach (Type controllerType in GetControllerTypesToRegister(container, assemblies))
            {
                Registration registration = Lifestyle.Transient.CreateRegistration(controllerType, container);

                // Suppress the Disposable Transient Component warning, because MVC's controller factory
                // ensures correct disposal of controllers.
                registration.SuppressDiagnosticWarning(DiagnosticType.DisposableTransientComponent);

                container.AddRegistration(controllerType, registration);
            }
        }
Example #16
0
        private static void RegisterDomainValidators(Container container, Assembly assembly)
        {
            var matches = assembly.GetExportedTypes()
                          .Where(t => t.IsClass && !t.IsAbstract && IsDomainValidator(t))
                          .Select(t => new
            {
                Implementation = t,
                Services       = t.GetInterfaces().Where(i => IsGenericDomainValidator(i))
            });

            Registration registration;
            var          genericDomainValidatorTypes = new List <Type>();

            foreach (var match in matches)
            {
                if (match.Implementation.IsGenericType)
                {
                    var args = match.Implementation.GetGenericArguments();
                    if (args.Length > 2)
                    {
                        throw new NotSupportedException(
                                  $"Domain validators with more that two generic arguments are not supported. Invalid domain validator: {match.Implementation}" +
                                  "Hint: make the validator as an abstract type or modify the type to contain two generic arguments or less");
                    }

                    container.Register(match.Implementation, match.Implementation);
                    // Register the implementation as we will need the registration when adding root/child producers
                    // Open generic registrations cannot be retrieved with GetCurrentRegistrations so we have to store
                    // them separately
                    genericDomainValidatorTypes.Add(match.Implementation);
                    foreach (var serviceType in match.Services)
                    {
                        container.Collection.Append(serviceType, match.Implementation);
                    }

                    continue;
                }

                registration = Lifestyle.Transient.CreateRegistration(match.Implementation, container);
                container.AddRegistration(match.Implementation, registration);
                foreach (var serviceType in match.Services)
                {
                    container.Collection.Append(serviceType, registration);
                }
            }

            var metadata = new RegisteredValidationAssemblyMetadata(assembly, genericDomainValidatorTypes);

            container.Collection.AppendInstance(metadata);
        }
Example #17
0
        /// <summary>
        /// Cross-wires an ASP.NET Core or third party service to the container, to allow the service to be
        /// injected into components that are built by the container.
        /// </summary>
        /// <param name="container">The container.</param>
        /// <param name="serviceType">The type of service object to ross-wire.</param>
        /// <param name="builder">The IApplicationBuilder to retrieve the service object from.</param>
        public static void CrossWire(this Container container, Type serviceType, IApplicationBuilder builder)
        {
            if (container == null)
            {
                throw new ArgumentNullException(nameof(container));
            }

            if (serviceType == null)
            {
                throw new ArgumentNullException(nameof(serviceType));
            }

            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            CrossWireContext context = GetCrossWireContext(container);

            Lifestyle lifestyle = DetermineLifestyle(serviceType, context.Services);

            Registration registration;

            if (lifestyle == Lifestyle.Singleton)
            {
                registration = lifestyle.CreateRegistration(
                    serviceType,
                    () => builder.ApplicationServices.GetRequiredService(serviceType),
                    container);
            }
            else
            {
                IHttpContextAccessor accessor = GetHttpContextAccessor(builder);

                EnsureServiceScopeIsRegistered(context, container, builder);

                registration = lifestyle.CreateRegistration(
                    serviceType,
                    () => GetServiceProvider(accessor, container).GetRequiredService(serviceType),
                    container);
            }

            if (lifestyle == Lifestyle.Transient && typeof(IDisposable).IsAssignableFrom(serviceType))
            {
                registration.SuppressDiagnosticWarning(DiagnosticType.DisposableTransientComponent,
                                                       justification: "This is a cross-wired service. ASP.NET Core will ensure it gets disposed.");
            }

            container.AddRegistration(serviceType, registration);
        }
        /// <summary>
        /// Cross-wires a registration made in the ASP.NET configuration into Simple Injector with the
        /// <see cref="Lifestyle.Transient">Transient</see> lifestyle, to allow that instance to be injected
        /// into application components.
        /// </summary>
        /// <typeparam name="TService">The type of the ASP.NET abstraction to cross-wire.</typeparam>
        /// <param name="container">The container to cross-wire that registration in.</param>
        /// <param name="applicationBuilder">The ASP.NET application builder instance that references all
        /// framework components.</param>
        public static void CrossWire <TService>(this Container container, IApplicationBuilder applicationBuilder)
            where TService : class
        {
            // Always use the transient lifestyle, because we have no clue what the lifestyle in ASP.NET is,
            // and scoped and singleton lifestyles will dispose instances, while ASP.NET controls them.
            var registration = Lifestyle.Transient.CreateRegistration(
                applicationBuilder.ApplicationServices.GetRequiredService <TService>,
                container);

            // Prevent Simple Injector from throwing exceptions when the service type is disposable (yuck!).
            // Implementing IDisposable on abstractions is a serious design flaw, but ASP.NET does it anyway :-(
            registration.SuppressDiagnosticWarning(DiagnosticType.DisposableTransientComponent, "Owned by ASP.NET");

            container.AddRegistration(typeof(TService), registration);
        }
        private void addRegistration(Type serviceType, Registration registration)
        {
            if (HasComponent(serviceType))
            {
                var existingRegistrations = GetExistingRegistrationsFor(serviceType);

                _container.Collection.Register(serviceType, existingRegistrations.Union(new[] { registration }));
            }
            else
            {
                _container.AddRegistration(serviceType, registration);
            }

            RegisterInterfaces(serviceType, registration.Lifestyle);
        }
        private static void RegisterControllerTypes(this Container container, IEnumerable <Type> types)
        {
            foreach (Type type in types.ToArray())
            {
                var registration = CreateConcreteRegistration(container, type);

                if (typeof(IDisposable).IsAssignableFrom(type))
                {
                    registration.SuppressDiagnosticWarning(
                        DiagnosticType.DisposableTransientComponent, "ASP.NET disposes controllers.");
                }

                container.AddRegistration(type, registration);
            }
        }
Example #21
0
        private static void RegisterControllerTypes(this Container container, IEnumerable <Type> types)
        {
            foreach (Type type in types.ToArray())
            {
                var registration = CreateConcreteRegistration(container, type);

                // Microsoft.AspNetCore.Mvc.Controller implements IDisposable (which is a design flaw).
                // This will cause false positives in Simple Injector's diagnostic services, so we suppress
                // this warning in case the registered type doesn't override Dispose from Controller.
                if (ShouldSuppressDisposingControllers(type))
                {
                    registration.SuppressDiagnosticWarning(
                        DiagnosticType.DisposableTransientComponent,
                        "Derived type doesn't override Dispose, so it can be safely ignored.");
                }

                container.AddRegistration(type, registration);
            }
        }
        /// <summary>
        /// Registers the Web API <see cref="IHttpController"/> types that available for the application. This
        /// method uses the configured <see cref="IHttpControllerTypeResolver"/> to determine which controller
        /// types to register.
        /// </summary>
        /// <param name="container">The container the controllers should be registered in.</param>
        /// <param name="configuration">The <see cref="HttpConfiguration"/> to use to get the Controller
        /// types to register.</param>
        /// <param name="assemblies">The assemblies to search.</param>
        /// <exception cref="ArgumentNullException">Thrown when one of the arguments is a null
        /// reference (Nothing in VB).</exception>
        public static void RegisterWebApiControllers(this Container container, HttpConfiguration configuration,
                                                     IEnumerable <Assembly> assemblies)
        {
            Requires.IsNotNull(container, "container");
            Requires.IsNotNull(configuration, "configuration");
            Requires.IsNotNull(assemblies, "assemblies");

            IAssembliesResolver assembliesResolver = new AssembliesResolver(assemblies);

            var controllerTypes = GetControllerTypesFromConfiguration(configuration, assembliesResolver);

            foreach (Type controllerType in controllerTypes)
            {
                Registration registration = Lifestyle.Transient.CreateRegistration(controllerType, container);

                // Suppress the Disposable Transient Component warning, because MVC's controller factory
                // ensures correct disposal of controllers.
                registration.SuppressDiagnosticWarning(DiagnosticType.DisposableTransientComponent);

                container.AddRegistration(controllerType, registration);
            }
        }
Example #23
0
        private static void RegisterDomainValidators(Container container, Assembly assembly)
        {
            var matches = assembly.GetExportedTypes().Where(x =>
            {
                var typeInfo = x.GetTypeInfo();

                return(typeInfo.IsClass && !typeInfo.IsAbstract && typeInfo.IsAssignableToGenericType(typeof(IDomainValidator <>)));
            });

            foreach (var match in matches)
            {
                var serviceType = match.GetGenericType(typeof(IDomainValidator <>));
                if (serviceType == null)
                {
                    continue;
                }

                var registration = Lifestyle.Scoped.CreateRegistration(match, container);
                container.AddRegistration(match, registration);
                container.Collection.Append(serviceType, registration);
            }
        }
        /// <summary>
        /// Cross-wires an ASP.NET Core or third party service to the container, to allow the service to be
        /// injected into components that are built by the container.
        /// </summary>
        /// <param name="container">The container.</param>
        /// <param name="serviceType">The type of service object to ross-wire.</param>
        /// <param name="builder">The IApplicationBuilder to retrieve the service object from.</param>
        public static void CrossWire(this Container container, Type serviceType, IApplicationBuilder builder)
        {
            if (container == null)
            {
                throw new ArgumentNullException(nameof(container));
            }

            if (serviceType == null)
            {
                throw new ArgumentNullException(nameof(serviceType));
            }

            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            CrossWireServiceScope(container, builder);

            Registration registration = CreateCrossWireRegistration(container, serviceType, builder);

            container.AddRegistration(serviceType, registration);
        }
        public void Configuration(IAppBuilder app)
        {
            ConfigureAuth(app);

            // scan assemblies for types
            var currentAssembly = typeof(Startup).Assembly;
            var componentMap = AutoRegistration.GetComponentMap(currentAssembly
                , x => typeof(IController).IsAssignableFrom(x)
                , currentAssembly
                , x => x.IsInterface);

            // init conventions for automapper
            StaticAutoMapperWrapper.Init(cfg =>
            {
                ConventionalProfile.Scan(currentAssembly);
                cfg.AddProfile<ConventionalProfile>();
            });

            // init IOC-container
            var container = new Container();
            container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();

            var am = Lifestyle.Singleton.CreateRegistration(() => new StaticAutoMapperWrapper(), container);
            container.AddRegistration(typeof(IProjector), am);
            container.AddRegistration(typeof(IMapper), am);

            // Fake Context
            var reg = Lifestyle.Singleton.CreateRegistration(() => new FakeContext(new[] {
                new Product()
                {
                    Category = new Category()
                    {
                        Rating = 100500
                    },
                    Id = 1,
                    Name = "1 Product",
                    Price = 100500,
                }
                , new Product()
                {
                    Category = new Category(),
                    Id = 2,
                    Name = "2 Product",
                    Price = 200500
                }

            }), container);

            container.AddRegistration(typeof(ILinqProvider), reg);
            container.AddRegistration(typeof(IUnitOfWork), reg);

            foreach (var kv in componentMap)
            {
                container.Register(kv.Key, kv.Value, Lifestyle.Scoped);
            }

            // This is an extension method from the integration package.
            container.RegisterMvcControllers(Assembly.GetExecutingAssembly());

            container.Verify();

            DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
        }