title: Change injected object at runtime
body: <p>I want to have multiples implementation of the IUserRepository each implementation will work with a database type either MongoDB or any SQL database. To do this I have ITenant interface that have a connection string and other tenant configuration. The tenant is been injected into IUserRepository either MongoDB or any SQLDB implementation. What I need to know is how properly change the injected repository to choose the database base on the tenant.</p>
  
  <p><strong>Interfaces</strong>    </p>
  
  <pre><code>public interface IUserRepository 
  {
      string Login(string username, string password);
      string Logoff(Guid id);
  }
  
  public class User
  {
      public Guid Id { get; set; }
      public string Username { get; set; }
      public string Password { get; set; }
      public string LastName { get; set; }
      public string FirstName { get; set; }
  
  }
  
  public interface ITenant
  {
      string CompanyName { get; }
      string ConnectionString { get; }
      string DataBaseName { get; }
      string EncriptionKey { get; }
  
  }
  </code></pre>
  
  <p>Is important to know that the tenant id is been pass to an API via header request</p>
  
  <p><strong>StartUp.cs</strong> </p>
  
  <pre><code>// set inject httpcontet to the tenant implemantion
  services.AddTransient&lt;IHttpContextAccessor, HttpContextAccessor&gt;();
  
  // inject tenant
  services.AddTransient&lt;ITenant, Tenant&gt;();
  
  // inject mongo repository but I want this to be programmatically
  services.AddTransient&lt;IUserRepository, UserMongoRepository&gt;();
  </code></pre>
  
  <p><strong>Sample Mongo Implementation</strong></p>
  
  <pre><code>public class UserMongoRepository : IUserRepository
  {
  
      protected ITenant Tenant 
  
      public UserMongoRepository(ITenant tenant) :
          base(tenant)
      {
          this.Tenant = tenant;
      }
  
      public string Login(string username, string password)
      {
  
          var query = new QueryBuilder&lt;User&gt;().Where(x =&gt; x.Username == username);
          var client = new MongoClient(this.Tenant.ConnectionString);var server = client.GetServer();
          var database =  client.GetServer().GetDatabase(this.Tenant.DataBaseName);
          var user = database.GetCollection&lt;User&gt;.FindAs&lt;User&gt;(query).AsQueryable().FirstOrDefault();
  
          if (user == null)
              throw new Exception("invalid username or password");
  
          if (user.Password != password)
              throw new Exception("invalid username or password");
  
           return "Sample Token";
  
      }
  
      public string Logoff(Guid id)
      {
  
          throw new NotImplementedException();
      }
  
  }
  </code></pre>
  
  <p><strong>Tenant</strong></p>
  
  <pre><code>public class Tenant : ITenant
  {
  
      protected IHttpContextAccessor Accesor;
      protected IConfiguration Configuration;
  
      public Tenant(IHttpContextAccessor accesor, IDBConfiguration config)
      {
          this.Accesor = accesor;
          this.Configuration = new Configuration().AddEnvironmentVariables();
          if (!config.IsConfigure)
              config.ConfigureDataBase();
      }
  
  
      private string _CompanyName;
      public string CompanyName
      {
          get
          {
              if (string.IsNullOrWhiteSpace(_CompanyName))
              {
                  _CompanyName = this.Accesor.Value.Request.Headers["Company"];
                  if (string.IsNullOrWhiteSpace(_CompanyName))
                      throw new Exception("Invalid Company");
              }
              return _CompanyName;
          }
      }
  
      private string _ConnectionString;
      public string ConnectionString
      {
          get
          {
              if (string.IsNullOrWhiteSpace(_ConnectionString))
              {
                  _ConnectionString = this.Configuration.Get(this.CompanyName + "_" + "ConnectionString");
                  if (string.IsNullOrWhiteSpace(_ConnectionString))
                      throw new Exception("Invalid ConnectionString Setup");
              }
              return _ConnectionString;
          }
      }
  
      private string _EncriptionKey;
      public string EncriptionKey
      {
          get
          {
              if (string.IsNullOrWhiteSpace(_EncriptionKey))
              {
                  _EncriptionKey = this.Configuration.Get(this.CompanyName + "_" + "EncriptionKey");
                  if (string.IsNullOrWhiteSpace(_EncriptionKey))
                      throw new Exception("Invalid Company Setup");
              }
              return _EncriptionKey;
          }
      }
  
      private string _DataBaseName;
      public string DataBaseName
      {
          get
          {
              if (string.IsNullOrWhiteSpace(_DataBaseName))
              {
                  _DataBaseName = this.Configuration.Get(this.CompanyName + "_" + "DataBaseName");
                  if (string.IsNullOrWhiteSpace(_DataBaseName))
                      throw new Exception("Invalid Company Setup");
              }
              return _DataBaseName;
          }
      }
  }
  </code></pre>
  
  <p><strong>Controller</strong></p>
  
  <pre><code>public class UsersController : Controller
  {
      protected IUserRepository DataService;
  
      public UsersController(IUserRepository dataService)
      {
          this.DataService = dataService;
      }
  
      // the controller implematation
  
  }
  </code></pre>