The CustomUIDGeneration example demonstrates how to use the DCF to customize the generation of UIDs.
Classes
Class | Description | |
---|---|---|
Program |
This example demonstrates several approaches on how to generate custom UIDs.
|
Remarks
Supported OS Platforms:
- Windows - .Net Framework 4.7.2 64-bit and 32-bit
- Windows - .Net Core 2.1 64-bit and 32-bit
- Linux - .Net Core 2.1 64-bit
Examples
CustomUIDGeneration Sample Code
public class Program { /// <summary> /// Main entry point for the CustomUIDGeneration example. /// </summary> public static void Main() { try { // Default prefixes, for comparision with examples below UidFactory tempFactory = new UidFactory(null, null); string defaultOrganizationPrefix = tempFactory.DefaultOrganizationPrefix; string defaultSystemPrefix = tempFactory.DefaultSystemPrefix; Console.WriteLine("Default org prefix: {0}", defaultOrganizationPrefix); Console.WriteLine("Default sys prefix: {0}", defaultSystemPrefix); // Example custom prefixes. These would be defined for use by a specific // vendor, organization or company, or for a particular desired purpose. string customOrganizationPrefix = "1.2.3.4.5.6.7"; string customSystemPrefix = "9999999999"; Console.WriteLine("Custom org prefix: {0}", customOrganizationPrefix); Console.WriteLine("Custom sys prefix: {0}", customSystemPrefix); Console.WriteLine(); // Generate a UID using the default UID factory, for comparison with examples below Console.WriteLine("Generated UID (default): {0}", DataDictionary.CreateUid()); // Generate a UID using the UuidDerivedUidFactory as per the DICOM spec. DataDictionary.UidFactory = new UuidDerivedUidFactory(); Console.WriteLine("UuidDerived UID (with 2.25): {0}", DataDictionary.CreateUid()); // Generate a UID using the custom organization prefix only DataDictionary.UidFactory = new UidFactory(customOrganizationPrefix, null); Console.WriteLine("Use org prefix (custom): {0}", DataDictionary.CreateUid()); // Generate a UID using the custom system prefix only DataDictionary.UidFactory = new UidFactory(null, customSystemPrefix); Console.WriteLine("Use sys prefix (custom): {0}", DataDictionary.CreateUid()); // Generate a UID using both custom prefixes only DataDictionary.UidFactory = new UidFactory(customOrganizationPrefix, customSystemPrefix); Console.WriteLine("sys+org prefix (custom): {0}", DataDictionary.CreateUid()); // Reset the UID factory and generate using default UID factory DataDictionary.UidFactory = null; // assigning null resets it Console.WriteLine("Generated UID (default): {0}", DataDictionary.CreateUid()); Console.WriteLine(); // Generate N UIDs using default UID factory DataDictionary.UidFactory = null; const int N = 10; for (int i = 0; i < N; i++) { Console.WriteLine("Generated UID (default) {0}: {1}", i + 1, DataDictionary.CreateUid()); } Console.WriteLine(); // Generate N UIDs using the UuidDerivedUidFactory DataDictionary.UidFactory = new UuidDerivedUidFactory(); for (int i = 0; i < N; i++) { Console.WriteLine("Generated UID (from UUID) {0}: {1}", i + 1, DataDictionary.CreateUid()); } Console.WriteLine(); // Generate N UIDs using custom UID factory DataDictionary.UidFactory = new UidFactory(customOrganizationPrefix, customSystemPrefix); for (int i = 0; i < N; i++) { Console.WriteLine("Generated UID (custom) {0}: {1}", i + 1, DataDictionary.CreateUid()); } Console.WriteLine(); // Generate N UIDs using an extended UID factory DataDictionary.UidFactory = new CustomUidFactory(3); for (int i = 0; i < N; i++) { Console.WriteLine("Generated UID (extended) {0}: {1}", i + 1, DataDictionary.CreateUid()); } } catch (Exception e) { Console.WriteLine("Error during execution: {0}", e); Environment.ExitCode = 1; } if (Debugger.IsAttached) { Console.Write("Press any key to continue . . . "); Console.ReadKey(); } } /// <summary> /// This class implements the IUidFactory interface. The implementation creates a UID from a UUID /// according to the description in Chapter 3.5 Appendix B.2 using the root "2.25". /// </summary> /// <remarks> /// <para> /// From the specification: /// The implementation treats the 128 bit UUID as an integer which may be up to 39 digits long. /// Leading zeros must be suppressed. /// </para> /// <para> /// A UUID derived UID may be appropriate for dynamically created UIDs, such as SOP Instance UIDs, /// but is usually not appropriate for UIDs determined during application software design, such /// as private SOP Class or Transfer Syntax UIDs, or Implementation Class UIDs. /// </para> /// </remarks> internal class UuidDerivedUidFactory : IUidFactory { public string CreateUid() { string hexGuid = "0" + Guid.NewGuid().ToString("N"); BigInteger bigInt = BigInteger.Parse(hexGuid, NumberStyles.HexNumber); string uid = String.Format("2.25.{0}", bigInt.ToString("D", CultureInfo.InvariantCulture)); return uid; } public bool IsValidUid(string uid) { return DicomUtils.IsUidValid(uid); } } /// <summary> /// You can extend UidFactory and override the protected <see cref="UidFactory.MakeUid">MakeUid</see> /// method to use your own algorithm from creating uids. /// </summary> /// <remarks> /// <para> /// The following factory assumes you have acquired the organizational prefix 1.2.3.4.5, which is unlikely. /// The algorithm used here creates a new guid every 3 iterations and appends a counter value to ensure uniqueness. /// Other algorithms might encode the mac address, cpu id, or the date and time, etc. /// </para> /// <para> /// Writing your own algorithm is not to be take lightly. The uid must start and end with a number, may only /// contain the digits 0-9 and periods, and must be 64 characters or less, including the periods. Multiple periods /// in succession are not allowed. Leading 0s in a numeric item are not allowed, unless the item is 0 by itself. /// </para> /// </remarks> internal class CustomUidFactory : UidFactory { private const string OrgPrefix = "1.2.3.4.5"; private const int DefaultInterval = 65536; private readonly StringBuilder _sb = new StringBuilder(); private int _counter /*= 0*/; private readonly int _interval; /// <summary> /// Constructor with optional specification of guid reset interval. /// </summary> /// <param name="interval">How often the guid is reset.</param> public CustomUidFactory(int interval = DefaultInterval) { _interval = interval; if (_interval <= 0) _interval = DefaultInterval; } /// <summary> /// Override the MakeUid method to do your own thing. This method is called under lock by <see cref="UidFactory.CreateUid"/>. /// The returned uid is validated by the <see cref="UidFactory.IsValidUid"/> method. This method relies on the /// <see cref="Guid.NewGuid"/> to guarantee the uniqueness of the generated UIDs. /// </summary> /// <returns>A UID string.</returns> protected override string MakeUid() { if (_counter == 0 || _sb.Length == 0) { string[] items = Guid.NewGuid().ToString("D").Split('-'); _sb.Length = 0; _sb.Append(OrgPrefix); foreach (string item in items) { _sb.Append("."); _sb.Append(Int64.Parse(item, NumberStyles.AllowHexSpecifier).ToString("D")); } } string result = String.Format("{0}.{1:D}", _sb, _counter + 1); _counter = (_counter + 1) % _interval; return result; } }