using System; using System.Reflection; using Abp.Extensions; namespace Abp { /// /// Used to identify a user. /// [Serializable] public class UserIdentifier : IUserIdentifier { /// /// Tenant Id of the user. /// Can be null for host users in a multi tenant application. /// public int? TenantId { get; protected set; } /// /// Id of the user. /// public long UserId { get; protected set; } /// /// Initializes a new instance of the class. /// protected UserIdentifier() { } /// /// Initializes a new instance of the class. /// /// Tenant Id of the user. /// Id of the user. public UserIdentifier(int? tenantId, long userId) { TenantId = tenantId; UserId = userId; } /// /// Parses given string and creates a new object. /// /// /// Should be formatted one of the followings: /// /// - "userId@tenantId". Ex: "42@3" (for tenant users). /// - "userId". Ex: 1 (for host users) /// public static UserIdentifier Parse(string userIdentifierString) { if (userIdentifierString.IsNullOrEmpty()) { throw new ArgumentNullException(nameof(userIdentifierString), "userAtTenant can not be null or empty!"); } var splitted = userIdentifierString.Split('@'); if (splitted.Length == 1) { return new UserIdentifier(null, splitted[0].To()); } if (splitted.Length == 2) { return new UserIdentifier(splitted[1].To(), splitted[0].To()); } throw new ArgumentException("userAtTenant is not properly formatted", nameof(userIdentifierString)); } /// /// Creates a string represents this instance. /// Formatted one of the followings: /// /// - "userId@tenantId". Ex: "42@3" (for tenant users). /// - "userId". Ex: 1 (for host users) /// /// Returning string can be used in method to re-create identical object. /// public string ToUserIdentifierString() { if (TenantId == null) { return UserId.ToString(); } return UserId + "@" + TenantId; } public override bool Equals(object obj) { if (obj == null || !(obj is UserIdentifier)) { return false; } //Same instances must be considered as equal if (ReferenceEquals(this, obj)) { return true; } //Transient objects are not considered as equal var other = (UserIdentifier)obj; //Must have a IS-A relation of types or must be same type var typeOfThis = GetType(); var typeOfOther = other.GetType(); if (!typeOfThis.GetTypeInfo().IsAssignableFrom(typeOfOther) && !typeOfOther.GetTypeInfo().IsAssignableFrom(typeOfThis)) { return false; } return TenantId == other.TenantId && UserId == other.UserId; } /// public override int GetHashCode() { return TenantId == null ? (int)UserId : (int)(TenantId.Value ^ UserId); } /// public static bool operator ==(UserIdentifier left, UserIdentifier right) { if (Equals(left, null)) { return Equals(right, null); } return left.Equals(right); } /// public static bool operator !=(UserIdentifier left, UserIdentifier right) { return !(left == right); } public override string ToString() { return ToUserIdentifierString(); } } }