using Newtonsoft.Json; using System; using System.Collections.Generic; namespace Pilz.Cryptography; [JsonConverter(typeof(Json.Converters.UniquieIDStringJsonConverter))] public class UniquieID : IUniquieID { protected static ulong currentSimpleID = 0; [JsonProperty(nameof(ID))] protected string _iD; [JsonIgnore] public virtual bool SimpleMode { get; } [JsonIgnore] public virtual bool GenerateOnGet { get; } [JsonIgnore] public virtual bool HasID => !string.IsNullOrEmpty(_iD); [JsonIgnore] public virtual string ID { get { if (GenerateOnGet) GenerateIfNull(); return _iD; } internal set => _iD = value; } public UniquieID() : this(UniquieIDGenerationMode.None) { } public UniquieID(UniquieIDGenerationMode mode) : this(mode, false) { } public UniquieID(UniquieIDGenerationMode mode, bool simpleMode) { SimpleMode = simpleMode; if (mode == UniquieIDGenerationMode.GenerateOnInit) GenerateIfNull(); else if (mode == UniquieIDGenerationMode.GenerateOnGet) GenerateOnGet = true; } [Obsolete] public UniquieID(bool autoGenerate) : this(autoGenerate ? UniquieIDGenerationMode.GenerateOnInit : UniquieIDGenerationMode.None) { } public virtual void Generate() { if (SimpleMode) ID = GenerateSimple(); else ID = GenerateDefault(); } protected virtual string GenerateSimple() { return new Random().Next().ToString() + DateTime.Now.ToString("yyyyMMddHHmmssfffffff") + currentSimpleID++.ToString(); } protected virtual string GenerateDefault() { return Helpers.GenerateUniquieID(currentSimpleID++.ToString()); } public virtual void GenerateIfNull() { if (!HasID) Generate(); } public override string ToString() { return ID; } public override int GetHashCode() { return -1430039477 + EqualityComparer.Default.GetHashCode(_iD); } public override bool Equals(object obj) { if (obj is UniquieID iD) { if (ReferenceEquals(obj, iD)) return true; else { var leftHasID = iD.HasID; var rightHasID = HasID; if (!leftHasID && iD.GenerateOnGet) { iD.Generate(); leftHasID = iD.HasID; } if (!rightHasID && GenerateOnGet) { Generate(); rightHasID = HasID; } if (leftHasID && rightHasID) return _iD.Equals(iD._iD); } } return base.Equals(obj); } public static implicit operator string(UniquieID id) => id.ID; public static implicit operator UniquieID(string id) => new UniquieID() { ID = id }; public static implicit operator UniquieID(int id) => new UniquieID() { ID = Convert.ToString(id) }; public static bool operator ==(UniquieID left, UniquieID right) => left.ID.Equals(right.ID); public static bool operator !=(UniquieID left, UniquieID right) => !left.ID.Equals(right.ID); }