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.");
        }
        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 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.");
        }