public void InstancePerTenant_RootAndPerTenantDependencies()
        {
            var strategy = new StubTenantIdentificationStrategy()
            {
                TenantId = "tenant1"
            };
            var builder = new ContainerBuilder();
            builder.RegisterType<StubDependency3Impl>().As<IStubDependency3>().InstancePerTenant();
            var mtc = new MultitenantContainer(strategy, builder.Build());
            mtc.ConfigureTenant("tenant1", b => b.RegisterType<StubDependency1Impl1>().As<IStubDependency1>().InstancePerTenant());
            mtc.ConfigureTenant("tenant2", b => b.RegisterType<StubDependency1Impl1>().As<IStubDependency1>().InstancePerTenant());

            // Two resolutions for a single tenant
            var dep1 = mtc.Resolve<IStubDependency3>();
            var dep2 = mtc.Resolve<IStubDependency3>();

            // One resolution for a different tenant
            strategy.TenantId = "tenant2";
            var dep3 = mtc.Resolve<IStubDependency3>();

            Assert.AreSame(dep1, dep2, "The two dependencies resolved for the first tenant should be the same.");
            Assert.AreNotSame(dep1, dep3, "The dependencies resolved across tenants should not be the same.");
            Assert.AreSame(dep1.Dependency, dep2.Dependency, "The two sub-dependencies resolved for the first tenant should be the same.");
            Assert.AreNotSame(dep1.Dependency, dep3.Dependency, "The sub-dependencies resolved across tenants should not be the same.");
        }
Example #2
0
        /// <summary>
        /// Configures the multitenant dependency container.
        /// </summary>
        private static IContainer ConfigureDependencies()
        {
            // Register default dependencies in the application container.
            var builder = new ContainerBuilder();
            builder.RegisterType<Consumer>().As<IDependencyConsumer>().InstancePerDependency();
            builder.RegisterType<BaseDependency>().As<IDependency>().SingleInstance();
            var appContainer = builder.Build();

            // Create the multitenant container.
            var mtc = new MultitenantContainer(_tenantIdentifier, appContainer);

            // Configure overrides for tenant 1. Tenant 1 registers their dependencies
            // as instance-per-dependency.
            mtc.ConfigureTenant('1', b => b.RegisterType<Tenant1Dependency>().As<IDependency>().InstancePerDependency());

            // Configure overrides for tenant 2. Tenant 2 registers their dependencies
            // as singletons.
            mtc.ConfigureTenant('2', b => b.RegisterType<Tenant2Dependency>().As<IDependency>().SingleInstance());

            // Configure overrides for the default tenant. That means the default
            // tenant will have some different dependencies than other unconfigured
            // tenants.
            mtc.ConfigureTenant(null, b => b.RegisterType<DefaultTenantDependency>().As<IDependency>().SingleInstance());

            return mtc;
        }
        protected void RegisterServices()
        {
            var tenantIdStrategy = new RouteDataItemTenantIdentificationStrategy("tenant");

            var builder = new ContainerBuilder();

            // Register your MVC controllers.
            builder.RegisterControllers(typeof(MvcApplication).Assembly);

            // OPTIONAL: Register model binders that require DI.
            builder.RegisterModelBinders(Assembly.GetExecutingAssembly());
            builder.RegisterModelBinderProvider();

            // OPTIONAL: Register web abstractions like HttpContextBase.
            builder.RegisterModule<AutofacWebTypesModule>();

            // OPTIONAL: Enable property injection in view pages.
            builder.RegisterSource(new ViewRegistrationSource());

            // OPTIONAL: Enable property injection into action filters.
            builder.RegisterFilterProvider();

            // Create the multitenant container and the tenant overrides.
            var mtc = new MultitenantContainer(tenantIdStrategy, builder.Build());
            AddTenant(mtc, "a");
            AddTenant(mtc, "b");

            DependencyResolver.SetResolver(new AutofacDependencyResolver(mtc));
        }
        public void Configuration(IAppBuilder app)
        {
            IContainer container = RegisterServices();
            PrincipalTenantIdentificationStrategy tenantStrategy = new PrincipalTenantIdentificationStrategy();
            MultitenantContainer mtc = new MultitenantContainer(tenantStrategy, container);
            HttpConfiguration config = new HttpConfiguration();
            config.Routes.MapHttpRoute("DefaultHttpRoute", "api/{controller}");

            app.UseAutofacContainer(mtc)
               .Use<RandomTextMiddleware>()
               .UseWebApiWithContainer(config);
        }
 public void BeginLifetimeScope_ChildScopeCanBeTagged()
 {
     var strategy = new StubTenantIdentificationStrategy()
     {
         TenantId = "tenant1"
     };
     var mtc = new MultitenantContainer(strategy, new ContainerBuilder().Build());
     using (var nestedScope = mtc.BeginLifetimeScope("tag"))
     {
         Assert.AreEqual("tag", nestedScope.Tag, "The child scope could not be tagged.");
     }
 }
Example #6
0
        public void RegisterDependencies(HttpConfiguration config) {

            var builder = new ContainerBuilder();
            builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

            // creates a logger instance per tenant
            builder.RegisterType<LoggerService>().As<ILoggerService>().InstancePerTenant();

            var mtc = new MultitenantContainer(
                new RequestParameterTenantIdentificationStrategy("tenant"),
                builder.Build());

            config.DependencyResolver = new AutofacWebApiDependencyResolver(mtc);
        }
 public void BeginLifetimeScope_ChildScopeCanBeConfigured()
 {
     var strategy = new StubTenantIdentificationStrategy()
     {
         TenantId = "tenant1"
     };
     var mtc = new MultitenantContainer(strategy, new ContainerBuilder().Build());
     mtc.ConfigureTenant("tenant1", b => b.RegisterType<StubDependency1Impl1>().As<IStubDependency1>());
     using (var nestedScope = mtc.BeginLifetimeScope(b => b.RegisterType<StubDependency1Impl2>().As<IStubDependency1>()))
     {
         var nestedDependency = nestedScope.Resolve<IStubDependency1>();
         Assert.IsInstanceOf<StubDependency1Impl2>(nestedDependency, "The child scope was not properly configured.");
     }
 }
 public void BeginLifetimeScope_CreatesLifetimeScopeForCurrentTenant()
 {
     var strategy = new StubTenantIdentificationStrategy()
     {
         TenantId = "tenant1"
     };
     var mtc = new MultitenantContainer(strategy, new ContainerBuilder().Build());
     mtc.ConfigureTenant("tenant1", b => b.RegisterType<StubDependency1Impl2>().As<IStubDependency1>().InstancePerLifetimeScope());
     var tenantScope = mtc.GetCurrentTenantScope();
     var tenantDependency = tenantScope.Resolve<IStubDependency1>();
     using (var nestedScope = mtc.BeginLifetimeScope())
     {
         var nestedDependency = nestedScope.Resolve<IStubDependency1>();
         Assert.AreNotSame(tenantDependency, nestedDependency, "The dependency should be registered, but the scope should resolve a new instance.");
     }
 }
        private static IContainer RegisterServices(ContainerBuilder builder, ITenantIdentificationStrategy idStrategy) {

            builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
            builder.Register(c => idStrategy).As<ITenantIdentificationStrategy>();
            builder.Register(c => {
                
                ITenantIdentificationStrategy s = c.Resolve<ITenantIdentificationStrategy>();
                object tenantId;
                s.TryIdentifyTenant(out tenantId);
                return tenantId;

            }).Keyed<object>("tenantId");

            // creates a logger instance per tenant
            builder.RegisterType<LoggerService>()
                .As<ILoggerService>().WithParameter((pi, c) => pi.Name == "tenant",
                    (pi, c) => c.ResolveKeyed<object>("tenantId")).InstancePerTenant();

            MultitenantContainer mtc = new MultitenantContainer(
                idStrategy, builder.Build());

            return mtc;
        }
        public void Resolve_TenantLevelSingleton()
        {
            var builder = new ContainerBuilder();
            builder.RegisterType<StubDependency1Impl1>().As<IStubDependency1>().SingleInstance();

            var strategy = new StubTenantIdentificationStrategy()
            {
                TenantId = "tenant1"
            };
            var mtc = new MultitenantContainer(strategy, builder.Build());
            mtc.ConfigureTenant("tenant1", b => b.RegisterType<StubDependency1Impl2>().As<IStubDependency1>().SingleInstance());
            mtc.ConfigureTenant("tenant2", b => b.RegisterType<StubDependency1Impl2>().As<IStubDependency1>().SingleInstance());

            // Get the application-level dependency
            var appLevel = mtc.ApplicationContainer.Resolve<IStubDependency1>();

            // Two resolutions for a single tenant
            var dep1 = mtc.Resolve<IStubDependency1>();
            var dep2 = mtc.Resolve<IStubDependency1>();

            // One resolution for a different tenant
            strategy.TenantId = "tenant2";
            var dep3 = mtc.Resolve<IStubDependency1>();

            Assert.IsInstanceOf<StubDependency1Impl2>(dep1, "Tenant 1's dependency should be the override value.");
            Assert.IsInstanceOf<StubDependency1Impl2>(dep3, "Tenant 2's dependency should be the override value.");
            Assert.IsInstanceOf<StubDependency1Impl1>(appLevel, "The application's dependency should be the base value.");
            Assert.AreSame(dep1, dep2, "The two dependencies resolved for the first tenant should be the same.");
            Assert.AreNotSame(dep1, dep3, "The dependencies resolved across tenants should not be the same.");
            Assert.AreNotSame(dep1, appLevel, "The dependencies resolved at the tenant level should not be the same as the ones at the application level.");
        }
 public void Resolve_TenantFallbackToApplicationContainer()
 {
     var builder = new ContainerBuilder();
     builder.RegisterType<StubDependency1Impl1>().As<IStubDependency1>();
     var strategy = new StubTenantIdentificationStrategy()
     {
         TenantId = "tenant1"
     };
     var mtc = new MultitenantContainer(strategy, builder.Build());
     Assert.IsInstanceOf<StubDependency1Impl1>(mtc.Resolve<IStubDependency1>(), "The wrong dependency type was resolved for the contextual tenant.");
 }
        public void Resolve_ApplicationLevelSingleton()
        {
            var builder = new ContainerBuilder();
            builder.RegisterType<StubDependency1Impl1>().As<IStubDependency1>().SingleInstance();
            var strategy = new StubTenantIdentificationStrategy()
            {
                TenantId = "tenant1"
            };
            var mtc = new MultitenantContainer(strategy, builder.Build());

            // Two resolutions for a single tenant
            var dep1 = mtc.Resolve<IStubDependency1>();
            var dep2 = mtc.Resolve<IStubDependency1>();

            // One resolution for a different tenant
            strategy.TenantId = "tenant2";
            var dep3 = mtc.Resolve<IStubDependency1>();

            Assert.AreSame(dep1, dep2, "The two dependencies resolved for the first tenant should be the same.");
            Assert.AreSame(dep1, dep3, "The dependencies resolved across tenants should be the same.");
        }
 public void GetTenantScope_SubsequentRetrievalsGetTheSameLifetimeScope()
 {
     var strategy = new StubTenantIdentificationStrategy()
     {
         TenantId = "tenant1"
     };
     var mtc = new MultitenantContainer(strategy, new ContainerBuilder().Build());
     mtc.ConfigureTenant("tenant1", b => b.RegisterType<StubDependency1Impl2>().As<IStubDependency1>());
     var scope1 = mtc.GetTenantScope("tenant1");
     var scope2 = mtc.GetTenantScope("tenant1");
     Assert.AreSame(scope1, scope2, "The tenant scope should not change across subsequent retrievals.");
 }
 public void GetTenantScope_NullIsDefaultTenant()
 {
     var strategy = new StubTenantIdentificationStrategy()
     {
         TenantId = "tenant1"
     };
     var mtc = new MultitenantContainer(strategy, new ContainerBuilder().Build());
     var scope = mtc.GetTenantScope(null);
     Assert.IsNotNull(scope, "The default tenant scope should not be null.");
     Assert.AreNotSame(mtc.ApplicationContainer, scope, "The default tenant scope should be a real scope, not just the application container.");
 }
 public void GetTenantScope_GetsTenantScopeForConfiguredTenant()
 {
     var strategy = new StubTenantIdentificationStrategy()
     {
         TenantId = "tenant1"
     };
     var mtc = new MultitenantContainer(strategy, new ContainerBuilder().Build());
     mtc.ConfigureTenant("tenant1", b => b.RegisterType<StubDependency1Impl2>().As<IStubDependency1>());
     var scope = mtc.GetTenantScope("tenant1");
     Assert.IsNotNull(scope, "The tenant scope retrieved not be null.");
     Assert.AreNotSame(mtc.ApplicationContainer, scope, "The tenant scope should be a real scope, not just the application container.");
 }
 /// <summary>
 /// Register dependencies to the multitenant container
 /// </summary>
 /// <param name="container">The Autofac multi tenant container</param>
 /// <remarks>
 /// Default implementation register all API objects
 /// </remarks>
 protected virtual void RegisterDependencies(
     MultitenantContainer container)
 {
     container.RegisterAll(TenantId, this.ThisAssembly);
 }
Example #17
0
        /// <summary>
        /// Handles the global application startup event.
        /// </summary>
        protected void Application_Start()
        {
            // Create the tenant ID strategy. Required for multitenant integration.
            var tenantIdStrategy = new RequestParameterTenantIdentificationStrategy("tenant");

            // Register application-level dependencies and controllers. Note that
            // we are manually registering controllers rather than all at the same
            // time because some of the controllers in this sample application
            // are for specific tenants.
            var builder = new ContainerBuilder();
            builder.RegisterType<HomeController>();
            builder.RegisterType<BaseDependency>().As<IDependency>();

            // Adding the tenant ID strategy into the container so controllers
            // can display output about the current tenant.
            builder.RegisterInstance(tenantIdStrategy).As<ITenantIdentificationStrategy>();

            // The service client is not different per tenant because
            // the service itself is multitenant - one client for all
            // the tenants and the service implementation switches.
            builder.Register(c => new ChannelFactory<IMultitenantService>(new BasicHttpBinding(), new EndpointAddress("http://localhost:63578/MultitenantService.svc"))).SingleInstance();
            builder.Register(c => new ChannelFactory<IMetadataConsumer>(new WSHttpBinding(), new EndpointAddress("http://localhost:63578/MetadataConsumer.svc"))).SingleInstance();

            // Register an endpoint behavior on the client channel factory that
            // will propagate the tenant ID across the wire in a message header.
            // On the service side, you'll need to read the header from incoming
            // message headers to reconstitute the incoming tenant ID.
            builder.Register(c =>
            {
                var factory = c.Resolve<ChannelFactory<IMultitenantService>>();
                factory.Opening += (sender, args) => factory.Endpoint.Behaviors.Add(new TenantPropagationBehavior<string>(tenantIdStrategy));
                return factory.CreateChannel();
            }).InstancePerRequest();
            builder.Register(c =>
            {
                var factory = c.Resolve<ChannelFactory<IMetadataConsumer>>();
                factory.Opening += (sender, args) => factory.Endpoint.Behaviors.Add(new TenantPropagationBehavior<string>(tenantIdStrategy));
                return factory.CreateChannel();
            }).InstancePerRequest();

            // Create the multitenant container based on the application
            // defaults - here's where the multitenant bits truly come into play.
            var mtc = new MultitenantContainer(tenantIdStrategy, builder.Build());

            // Notice we configure tenant IDs as strings below because the tenant
            // identification strategy retrieves string values from the request
            // context. To use strongly-typed tenant IDs, create a custom tenant
            // identification strategy that returns the appropriate type.

            // Configure overrides for tenant 1 - dependencies, controllers, etc.
            mtc.ConfigureTenant("1",
                b =>
                {
                    b.RegisterType<Tenant1Dependency>().As<IDependency>().InstancePerDependency();
                    b.RegisterType<Tenant1Controller>().As<HomeController>();
                });

            // Configure overrides for tenant 2 - dependencies, controllers, etc.
            mtc.ConfigureTenant("2",
                b =>
                {
                    b.RegisterType<Tenant2Dependency>().As<IDependency>().SingleInstance();
                    b.RegisterType<Tenant2Controller>().As<HomeController>();
                });

            // Configure overrides for the default tenant. That means the default
            // tenant will have some different dependencies than other unconfigured
            // tenants.
            mtc.ConfigureTenant(null, b => b.RegisterType<DefaultTenantDependency>().As<IDependency>().SingleInstance());

            // Create the dependency resolver using the
            // multitenant container instead of the application container.
            DependencyResolver.SetResolver(new AutofacDependencyResolver(mtc));

            // Perform the standard MVC setup requirements.
            AreaRegistration.RegisterAllAreas();
            RegisterRoutes(RouteTable.Routes);
        }
 public void ComponentRegistry_ReturnsRegistryFromCurrentTenantLifetimeScope()
 {
     var strategy = new StubTenantIdentificationStrategy()
     {
         TenantId = "tenant1"
     };
     var mtc = new MultitenantContainer(strategy, new ContainerBuilder().Build());
     var scope = mtc.GetCurrentTenantScope();
     Assert.AreSame(scope.ComponentRegistry, mtc.ComponentRegistry, "The ComponentRegistry property should behave based on context.");
 }
Example #19
0
        private IDependencyResolver RegisterBuilderAutofacMultitenant(HttpConfiguration httpConfiguration)
        {
            // From http://docs.autofac.org/en/latest/advanced/multitenant.html#what-is-multitenancy

            var builder = new ContainerBuilder();
            var assembly = Assembly.GetExecutingAssembly();

            builder.RegisterModule(new SharedLibModule());
            //builder.RegisterType<HelloManager>().As<IHelloManager>().InstancePerRequest();

            // TODO: Make configurable
            builder.RegisterType<RequestParameterStrategy>().As<ITenantIdentificationStrategy>();

            // Standard API registration
            builder.RegisterWebApiFilterProvider(httpConfiguration);
            builder.RegisterApiControllers(assembly);

            var container = builder.Build();

            //if (container.IsRegistered<ITenantIdentificationStrategy>())

            var tenantStrategy = container.Resolve<ITenantIdentificationStrategy>();

            var mtc = new MultitenantContainer(tenantStrategy, container);

            //mtc.ConfigureTenant("A",
            //    b => b.RegisterType<HellloManagerA>().As<IHelloManager>()
            //        .InstancePerDependency());

            // Read assembly custom attribute
            var groupedAssemblies = LoadAssemblies().Select(ass => new
            {
                Assembly = ass,
                TenantAttribute = ass.GetCustomAttribute<TenantAttributeAttribute>()
            })
            .Where(o => o.TenantAttribute != null)
            .GroupBy(o => o.TenantAttribute.TenantId, o => o.Assembly);

            foreach (var group in groupedAssemblies)
            {
                // TODO: Log tenant being loaded at info level to give a way to debug issue.
                var grp = group;
                mtc.ConfigureTenant(grp.Key, cb =>
                {
                    cb.RegisterAssemblyModules(grp.ToArray());
                });
            }

            return new AutofacWebApiDependencyResolver(mtc);
        }
 public void Ctor_SetsProperties()
 {
     var container = new ContainerBuilder().Build();
     var strategy = new StubTenantIdentificationStrategy();
     var mtc = new MultitenantContainer(strategy, container);
     Assert.AreSame(container, mtc.ApplicationContainer, "The application container wasn't set.");
     Assert.AreSame(strategy, mtc.TenantIdentificationStrategy, "The tenant ID strategy wasn't set.");
 }
 public void ConfigureTenant_RequiresConfiguration()
 {
     var builder = new ContainerBuilder();
     var strategy = new StubTenantIdentificationStrategy()
     {
         TenantId = "tenant1"
     };
     var mtc = new MultitenantContainer(strategy, builder.Build());
     Assert.Throws<ArgumentNullException>(() => mtc.ConfigureTenant("tenant1", null));
 }
        /// <summary>
        /// Handles the global application startup event.
        /// </summary>
        protected void Application_Start(object sender, EventArgs e)
        {
            // Create the tenant ID strategy. Required for multitenant integration.
            var tenantIdStrategy = new OperationContextTenantIdentificationStrategy();

            // Register application-level dependencies and service implementations.
            // Note that we are registering the services as the interface type
            // because the .svc files refer to the interfaces. We could potentially
            // use named service types as well.
            var builder = new ContainerBuilder();
            builder.RegisterType<BaseImplementation>().As<IMultitenantService>();
            builder.RegisterType<BaseImplementation>().As<IMetadataConsumer>();
            builder.RegisterType<BaseDependency>().As<IDependency>();

            // Adding the tenant ID strategy into the container so services
            // can return output about the current tenant.
            builder.RegisterInstance(tenantIdStrategy).As<ITenantIdentificationStrategy>();

            // Create the multitenant container based on the application
            // defaults - here's where the multitenant bits truly come into play.
            var mtc = new MultitenantContainer(tenantIdStrategy, builder.Build());

            // Notice we configure tenant IDs as strings below because the tenant
            // identification strategy retrieves string values from the message
            // headers.

            // Configure overrides for tenant 1 - dependencies, service implementations, etc.
            mtc.ConfigureTenant("1",
                b =>
                {
                    b.RegisterType<Tenant1Dependency>().As<IDependency>().InstancePerDependency();
                    b.RegisterType<Tenant1Implementation>().As<IMultitenantService>();
                    b.RegisterType<Tenant1Implementation>().As<IMetadataConsumer>();
                });

            // Configure overrides for tenant 2 - dependencies, service implementations, etc.
            mtc.ConfigureTenant("2",
                b =>
                {
                    b.RegisterType<Tenant2Dependency>().As<IDependency>().SingleInstance();
                    b.RegisterType<Tenant2Implementation>().As<IMultitenantService>();
                    b.RegisterType<Tenant2Implementation>().As<IMetadataConsumer>();
                });

            // Configure overrides for the default tenant. That means the default
            // tenant will have some different dependencies than other unconfigured
            // tenants.
            mtc.ConfigureTenant(null, b => b.RegisterType<DefaultTenantDependency>().As<IDependency>().SingleInstance());

            // Multitenant service hosting requires use of a different service implementation
            // data provider that will allow you to define a metadata buddy class that isn't
            // tenant-specific.
            AutofacHostFactory.ServiceImplementationDataProvider = new MultitenantServiceImplementationDataProvider();

            // Add a behavior to service hosts that get created so incoming messages
            // get inspected and the tenant ID can be parsed from message headers.
            // For multitenancy to work, you need to know for which tenant a
            // given request is being made. In this case, the incoming message headers
            // expect to see a string for the tenant ID; if your tenant ID coming
            // from clients is different, change that here.
            AutofacHostFactory.HostConfigurationAction =
                host =>
                    host.Opening += (s, args) =>
                        host.Description.Behaviors.Add(new TenantPropagationBehavior<string>(tenantIdStrategy));

            // Finally, set the host factory application container on the multitenant
            // WCF host to a multitenant container. This is similar to standard
            // Autofac WCF integration.
            AutofacHostFactory.Container = mtc;

            // Note that the .svc file for your service needs to use the
            // Autofac.Extras.Multitenant.Wcf.AutofacServiceHostFactory or
            // Autofac.Extras.Multitenant.Wcf.AutofacWebServiceHostFactory rather
            // than the standard Autofac host factories.
        }
        public void Dispose_DisposesTenantLifetimeScopes()
        {
            var appDependency = new StubDisposableDependency();
            var tenantDependency = new StubDisposableDependency();
            var builder = new ContainerBuilder();
            builder.RegisterInstance(appDependency).OwnedByLifetimeScope();
            var strategy = new StubTenantIdentificationStrategy()
            {
                TenantId = "tenant1"
            };
            var mtc = new MultitenantContainer(strategy, builder.Build());
            mtc.ConfigureTenant("tenant1", b => b.RegisterInstance(tenantDependency).OwnedByLifetimeScope());

            // Resolve the tenant dependency so it's added to the list of things to dispose.
            // If you don't do this, it won't be queued for disposal and the test fails.
            mtc.Resolve<StubDisposableDependency>();

            mtc.Dispose();
            Assert.IsTrue(appDependency.IsDisposed, "The application scope didn't run Dispose.");
            Assert.IsTrue(tenantDependency.IsDisposed, "The tenant scope didn't run Dispose.");
        }
        private void AddTenant(MultitenantContainer mtc, string tenantId)
        {
            mtc.ConfigureTenant(tenantId,
                b =>
                {
                    var options = this.GetMyOptions(tenantId);

                    b.Register(c => new TestDbContext(options.ConnectionString))
                        .As<TestDbContext>()
                        .InstancePerDependency();

                    b.ConfigureOptions(options);
                });
        }
 public void ConfigureTenant_DoesNotAllowMultipleSubsequentRegistrationsForDefaultTenant()
 {
     var builder = new ContainerBuilder();
     builder.RegisterType<StubDependency1Impl1>().As<IStubDependency1>();
     var strategy = new StubTenantIdentificationStrategy()
     {
         TenantId = "tenant1"
     };
     var mtc = new MultitenantContainer(strategy, builder.Build());
     mtc.ConfigureTenant(null, b => b.RegisterType<StubDependency1Impl2>().As<IStubDependency1>());
     Assert.Throws<InvalidOperationException>(() => mtc.ConfigureTenant(null, b => b.RegisterType<StubDependency2Impl2>().As<IStubDependency2>()));
 }
 public void GetCurrentTenantScope_TenantNotFound()
 {
     var strategy = new StubTenantIdentificationStrategy()
     {
         TenantId = "tenant1",
         IdentificationSuccess = false
     };
     var mtc = new MultitenantContainer(strategy, new ContainerBuilder().Build());
     var current = mtc.GetCurrentTenantScope();
     var tenant = mtc.GetTenantScope(null);
     Assert.AreSame(tenant, current, "The current scope should be the default tenant scope for the unidentified tenant.");
 }
 public void GetCurrentTenantScope_ChangesByContext()
 {
     var strategy = new StubTenantIdentificationStrategy()
     {
         TenantId = "tenant1"
     };
     var mtc = new MultitenantContainer(strategy, new ContainerBuilder().Build());
     var tenant1a = mtc.GetCurrentTenantScope();
     strategy.TenantId = "tenant2";
     var tenant2 = mtc.GetCurrentTenantScope();
     strategy.TenantId = "tenant1";
     var tenant1b = mtc.GetCurrentTenantScope();
     Assert.AreSame(tenant1a, tenant1b, "Every time a specific tenant context is seen, the same current scope should be returned.");
     Assert.AreNotSame(tenant1a, tenant2, "When different tenant contexts are seen, different tenant scopes should be returned.");
 }
        /// <summary>
        /// Adds tenant-specific registrations to the container 
        /// </summary>
        /// <param name="container">Autofac multitenant container</param>
        public void Load(MultitenantContainer container)
        {
            container.NotNull(nameof(container));

            RegisterDependencies(container);
        }