title: How to overload UserManager.AddToRoleAsync(string userId, string role)
body: <p>I'm using Asp.net Identity Framework 2.1. I implement customized ApplicatoinUser, ApplicationRole, ApplicationUserRole, because I want to add support to multi-tenant, that is each user belongs to different companies, but I have 3 roles among all these companies, they are User, Admin and Approver.</p>
  
  <p>My ApplicationUserRole derived from IdentityUserRole, and have one more property: CompanyId. This property will indicate the user's role in this particular company. My code for these customized classes attached in bottom.</p>
  
  <p>My question is when I try to override ApplicationUserManager(Yes, it derived from UserManager too)'s <code>AddToRoleAsync</code>  , <code>IsInRoleAsync</code>  , I don't know how to deal with the new CompanyId,  looks like the existing function doesn't receive these companyId(or tenantId). </p>
  
  <p>Then when I'm trying to overload these functions with companyId included, I can't find the db context either in ApplicatoinUserManager nor its base class.</p>
  
  <p>Am I on the right track of adding tenantId/companyId to the application Role?</p>
  
  <p>I've referenced this answer: <a href="https://stackoverflow.com/questions/21246591/asp-net-multi-tenant-application-with-tenant-specific-roles/21246732#21246732">SO linkes</a>, and this blog.<a href="http://ecastexception.com/post/2014/10/26/ASPNET-Web-Api-and-Identity-20-Customizing-Identity-Models-and-Implementing-Role-Based-Authorization.aspx" rel="nofollow noreferrer">ASP.NET Web Api and Identity 2.0 - Customizing Identity Models and Implementing Role-Based Authorization</a></p>
  
  <p>My IdentityModels:</p>
  
  <pre><code>public class ApplicationUserLogin : IdentityUserLogin&lt;string&gt; { }
  public class ApplicationUserClaim : IdentityUserClaim&lt;string&gt; 
  {
  }
  public class ApplicationUserRole : IdentityUserRole&lt;string&gt; 
  {
      public string CompanyId { get; set; }
  }
  
  // You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more.
  public class ApplicationUser : IdentityUser&lt;string, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim&gt;//, IAppUser
  {
      public ApplicationUser()
      {
          this.Id = Guid.NewGuid().ToString();
      }
      public virtual string CompanyId { get; set; }
      public virtual List&lt;CompanyEntity&gt; Company { get; set; }
      public DateTime CreatedOn { get; set; }
  
      public async Task&lt;ClaimsIdentity&gt; GenerateUserIdentityAsync(ApplicationUserManager manager, string authenticationType)
      {
          // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
          var userIdentity = await manager.CreateIdentityAsync(this, authenticationType);
          // Add custom user claims here
          return userIdentity;
      }
  }
  
  // Must be expressed in terms of our custom UserRole:
  public class ApplicationRole : IdentityRole&lt;string, ApplicationUserRole&gt;
  {
      public ApplicationRole() {}
      public ApplicationRole(string name) : this()
      {
          this.Name = name;
      }
  
      // Add any custom Role properties/code here
      public string Description { get; set; }
  }
  
  // Most likely won't need to customize these either, but they were needed because we implemented
  // custom versions of all the other types:
  public class ApplicationUserStore: UserStore&lt;ApplicationUser, ApplicationRole, string,ApplicationUserLogin, ApplicationUserRole,ApplicationUserClaim&gt;, IUserStore&lt;ApplicationUser, string&gt;, IDisposable
  {
      public ApplicationUserStore()
          : this(new IdentityDbContext())
      {
          base.DisposeContext = true;
      }
  
      public ApplicationUserStore(DbContext context)
          : base(context)
      {
      }
  }
  
  public class ApplicationRoleStore
  : RoleStore&lt;ApplicationRole, string, ApplicationUserRole&gt;,
  IQueryableRoleStore&lt;ApplicationRole, string&gt;,
  IRoleStore&lt;ApplicationRole, string&gt;, IDisposable
  {
      public ApplicationRoleStore()
          : base(new IdentityDbContext())
      {
          base.DisposeContext = true;
      }
  
      public ApplicationRoleStore(DbContext context)
          : base(context)
      {
      }
  }
  </code></pre>
  
  <p>My IdentityConfig:</p>
  
  <pre><code>public class ApplicationUserManager
      : UserManager&lt;ApplicationUser, string&gt;
  {
      public ApplicationUserManager(IUserStore&lt;ApplicationUser, string&gt; store)
          : base(store) { }
  
      public static ApplicationUserManager Create(
          IdentityFactoryOptions&lt;ApplicationUserManager&gt; options,
          IOwinContext context)
      {
          var manager = new ApplicationUserManager(
              new UserStore&lt;ApplicationUser, ApplicationRole, string,
                  ApplicationUserLogin, ApplicationUserRole,
                  ApplicationUserClaim&gt;(context.Get&lt;ApplicationDbContext&gt;()));
  
          // Configure validation logic for usernames
          manager.UserValidator = new UserValidator&lt;ApplicationUser&gt;(manager)
          {
              AllowOnlyAlphanumericUserNames = false,
              RequireUniqueEmail = false
          };
  
          // Configure validation logic for passwords
          manager.PasswordValidator = new PasswordValidator
          {
              RequiredLength = 6,
              //RequireNonLetterOrDigit = true,
              //RequireDigit = true,
              //RequireLowercase = true,
              //RequireUppercase = true,
          };
          var dataProtectionProvider = options.DataProtectionProvider;
          if (dataProtectionProvider != null)
          {
              manager.UserTokenProvider =
                  new DataProtectorTokenProvider&lt;ApplicationUser&gt;(
                      dataProtectionProvider.Create("ASP.NET Identity"));
          }
  
          // add sms and email service provider
          manager.SmsService = new EMaySmsServiceProvider();
          manager.EmailService = new ConcordyaEmailServiceProvider();
  
          return manager;
      }
      public string GetCurrentCompanyId(string userName)
      {
          var user = this.FindByName(userName);
          if (user == null)
              return string.Empty;
  
          var currentCompany = string.Empty;
          if (user.Claims.Count &gt; 0)
          {
              currentCompany = user.Claims.Where(c =&gt; c.ClaimType == ConcordyaPayee.Core.Common.ConcordyaClaimTypes.CurrentCompanyId).FirstOrDefault().ClaimValue;
          }
          else
          {
              currentCompany = user.CurrentCompanyId;
          }
          return currentCompany;
      }
  
      public override Task&lt;IdentityResult&gt; AddToRoleAsync(string userId, string role, string companyId)
      { 
          return base.AddToRoleAsync(userId, role);
      }
  
      #region overrides for unit tests
      public override Task&lt;bool&gt; CheckPasswordAsync(ApplicationUser user, string password)
      {
          return base.CheckPasswordAsync(user, password);
      }
  
      public override Task&lt;ApplicationUser&gt; FindByNameAsync(string userName)
      {
          return base.FindByNameAsync(userName);
      }
      #endregion
  }
  
  public class ApplicationRoleManager : RoleManager&lt;ApplicationRole&gt;
  {
      public ApplicationRoleManager(IRoleStore&lt;ApplicationRole, string&gt; roleStore)
          : base(roleStore)
      {
  
      }
  
      public static ApplicationRoleManager Create(
          IdentityFactoryOptions&lt;ApplicationRoleManager&gt; options,
          IOwinContext context)
      {
          return new ApplicationRoleManager(
              new ApplicationRoleStore(context.Get&lt;ApplicationDbContext&gt;()));
      }
  }
  </code></pre>