From 91eebfb166f896107967fe5afea11fed5f18787c Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Wed, 10 Jan 2024 10:59:01 -0500 Subject: [PATCH 1/4] Add quick start --- OptimizelySDK.sln | 6 ++ QuickStart/Program.cs | 85 +++++++++++++++++++++++++++ QuickStart/Properties/AssemblyInfo.cs | 35 +++++++++++ QuickStart/QuickStart.csproj | 61 +++++++++++++++++++ 4 files changed, 187 insertions(+) create mode 100644 QuickStart/Program.cs create mode 100644 QuickStart/Properties/AssemblyInfo.cs create mode 100644 QuickStart/QuickStart.csproj diff --git a/OptimizelySDK.sln b/OptimizelySDK.sln index 4fb4cac3..5e9a17b7 100644 --- a/OptimizelySDK.sln +++ b/OptimizelySDK.sln @@ -28,6 +28,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OptimizelySDK.Net40", "Opti EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OptimizelySDK.NetStandard20", "OptimizelySDK.NetStandard20\OptimizelySDK.NetStandard20.csproj", "{CFEC91C6-B6E5-45D5-97D6-7081B0DC7453}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuickStart", "QuickStart\QuickStart.csproj", "{74BAE350-8779-413A-A88E-AFE6A0A84D28}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -62,6 +64,10 @@ Global {CFEC91C6-B6E5-45D5-97D6-7081B0DC7453}.Debug|Any CPU.Build.0 = Debug|Any CPU {CFEC91C6-B6E5-45D5-97D6-7081B0DC7453}.Release|Any CPU.ActiveCfg = Release|Any CPU {CFEC91C6-B6E5-45D5-97D6-7081B0DC7453}.Release|Any CPU.Build.0 = Release|Any CPU + {74BAE350-8779-413A-A88E-AFE6A0A84D28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {74BAE350-8779-413A-A88E-AFE6A0A84D28}.Debug|Any CPU.Build.0 = Debug|Any CPU + {74BAE350-8779-413A-A88E-AFE6A0A84D28}.Release|Any CPU.ActiveCfg = Release|Any CPU + {74BAE350-8779-413A-A88E-AFE6A0A84D28}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/QuickStart/Program.cs b/QuickStart/Program.cs new file mode 100644 index 00000000..3fecd399 --- /dev/null +++ b/QuickStart/Program.cs @@ -0,0 +1,85 @@ +using System; +using OptimizelySDK; + +namespace QuickStart +{ + public static class QuickStart + { + public static void Main() + { + // This Optimizely initialization is synchronous. For other methods, see the C# SDK reference. + var optimizelyClient = OptimizelyFactory.NewDefaultInstance("K4UmaV5Pk7cEh2hbcjgwe"); + if (!optimizelyClient.IsValid) + { + Console.WriteLine( + "Optimizely client invalid. " + + "Verify in Settings>Environments that you used the primary environment's SDK key"); + optimizelyClient.Dispose(); + } + + var hasOnFlags = false; + + /* + * To get rapid demo results, generate random users. + * Each user always sees the same variation unless you reconfigure the flag rule. + */ + var rnd = new Random(); + for (var i = 0; i < 10; i++) + { + var userId = rnd.Next(1000, 9999).ToString(); + + // Create a user context to bucket the user into a variation. + var user = optimizelyClient.CreateUserContext(userId); + + // "product_sort" corresponds to a flag key in your Optimizely project + var decision = user.Decide("product_sort"); + + // Did decision fail with a critical error? + if (string.IsNullOrEmpty(decision.VariationKey)) + { + Console.WriteLine(Environment.NewLine + Environment.NewLine + + "Decision error: " + string.Join(" ", decision.Reasons)); + continue; + } + + /* + * Get a dynamic configuration variable. + * "sort_method" corresponds to a variable key in your Optimizely project. + */ + var sortMethod = decision.Variables.ToDictionary()["sort_method"]; + + hasOnFlags = hasOnFlags || decision.Enabled; + + /* + * Mock what the user sees with print statements (in production, use flag variables to implement feature configuration) + */ + + // always returns false until you enable a flag rule in your Optimizely project + Console.WriteLine(Environment.NewLine + + $"Flag {(decision.Enabled ? "on" : "off")}. " + + $"User number {user.GetUserId()} saw " + + $"flag variation {decision.VariationKey} and got " + + $"products sorted by {sortMethod} config variable as part of " + + $"flag rule {decision.RuleKey}"); + } + + if (!hasOnFlags) + { + var projectId = optimizelyClient.ProjectConfigManager.GetConfig().ProjectId; + var projectSettingsUrl = + $"https://app.optimizely.com/v2/projects/{projectId}/settings/implementation"; + + Console.WriteLine(Environment.NewLine + Environment.NewLine + + "Flag was off for everyone. Some reasons could include:" + + Environment.NewLine + + "1. Your sample size of visitors was too small. Re-run, or increase the iterations in the FOR loop" + + Environment.NewLine + + "2. By default you have 2 keys for 2 project environments (dev/prod). Verify in Settings>Environments that you used the right key for the environment where your flag is toggled to ON." + + Environment.NewLine + Environment.NewLine + + $"Check your key at {projectSettingsUrl}"); + } + + optimizelyClient.Dispose(); + } + } +} diff --git a/QuickStart/Properties/AssemblyInfo.cs b/QuickStart/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..f442705c --- /dev/null +++ b/QuickStart/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("QuickStart")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("QuickStart")] +[assembly: AssemblyCopyright("Copyright © 2024")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("74BAE350-8779-413A-A88E-AFE6A0A84D28")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/QuickStart/QuickStart.csproj b/QuickStart/QuickStart.csproj new file mode 100644 index 00000000..31cf1bcc --- /dev/null +++ b/QuickStart/QuickStart.csproj @@ -0,0 +1,61 @@ + + + + + Debug + AnyCPU + {74BAE350-8779-413A-A88E-AFE6A0A84D28} + Exe + Properties + QuickStart + QuickStart + v4.8 + 512 + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + {4dde7faa-110d-441c-ab3b-3f31b593e8bf} + OptimizelySDK + + + + + + From 59d0e1b43d41a66cf7916bcf8a4cd17a698c2398 Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Wed, 10 Jan 2024 11:58:39 -0500 Subject: [PATCH 2/4] test: WIP validation before release --- QuickStart/App.config | 10 ++++ QuickStart/Program.cs | 107 ++++++++++++++--------------------- QuickStart/QuickStart.csproj | 7 +++ QuickStart/packages.config | 4 ++ 4 files changed, 65 insertions(+), 63 deletions(-) create mode 100644 QuickStart/App.config create mode 100644 QuickStart/packages.config diff --git a/QuickStart/App.config b/QuickStart/App.config new file mode 100644 index 00000000..f54a54db --- /dev/null +++ b/QuickStart/App.config @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/QuickStart/Program.cs b/QuickStart/Program.cs index 3fecd399..58543407 100644 --- a/QuickStart/Program.cs +++ b/QuickStart/Program.cs @@ -1,4 +1,6 @@ using System; +using System.Linq; +using Newtonsoft.Json; using OptimizelySDK; namespace QuickStart @@ -7,8 +9,7 @@ public static class QuickStart { public static void Main() { - // This Optimizely initialization is synchronous. For other methods, see the C# SDK reference. - var optimizelyClient = OptimizelyFactory.NewDefaultInstance("K4UmaV5Pk7cEh2hbcjgwe"); + var optimizelyClient = OptimizelyFactory.NewDefaultInstance("TbrfRLeKvLyWGusqANoeR"); if (!optimizelyClient.IsValid) { Console.WriteLine( @@ -16,69 +17,49 @@ public static void Main() "Verify in Settings>Environments that you used the primary environment's SDK key"); optimizelyClient.Dispose(); } + + const string USER_ID = "matjaz-user-2"; - var hasOnFlags = false; - - /* - * To get rapid demo results, generate random users. - * Each user always sees the same variation unless you reconfigure the flag rule. - */ - var rnd = new Random(); - for (var i = 0; i < 10; i++) - { - var userId = rnd.Next(1000, 9999).ToString(); - - // Create a user context to bucket the user into a variation. - var user = optimizelyClient.CreateUserContext(userId); - - // "product_sort" corresponds to a flag key in your Optimizely project - var decision = user.Decide("product_sort"); - - // Did decision fail with a critical error? - if (string.IsNullOrEmpty(decision.VariationKey)) - { - Console.WriteLine(Environment.NewLine + Environment.NewLine + - "Decision error: " + string.Join(" ", decision.Reasons)); - continue; - } - - /* - * Get a dynamic configuration variable. - * "sort_method" corresponds to a variable key in your Optimizely project. - */ - var sortMethod = decision.Variables.ToDictionary()["sort_method"]; - - hasOnFlags = hasOnFlags || decision.Enabled; - - /* - * Mock what the user sees with print statements (in production, use flag variables to implement feature configuration) - */ - - // always returns false until you enable a flag rule in your Optimizely project - Console.WriteLine(Environment.NewLine + - $"Flag {(decision.Enabled ? "on" : "off")}. " + - $"User number {user.GetUserId()} saw " + - $"flag variation {decision.VariationKey} and got " + - $"products sorted by {sortMethod} config variable as part of " + - $"flag rule {decision.RuleKey}"); - } - - if (!hasOnFlags) - { - var projectId = optimizelyClient.ProjectConfigManager.GetConfig().ProjectId; - var projectSettingsUrl = - $"https://app.optimizely.com/v2/projects/{projectId}/settings/implementation"; - - Console.WriteLine(Environment.NewLine + Environment.NewLine + - "Flag was off for everyone. Some reasons could include:" + - Environment.NewLine + - "1. Your sample size of visitors was too small. Re-run, or increase the iterations in the FOR loop" + - Environment.NewLine + - "2. By default you have 2 keys for 2 project environments (dev/prod). Verify in Settings>Environments that you used the right key for the environment where your flag is toggled to ON." + - Environment.NewLine + Environment.NewLine + - $"Check your key at {projectSettingsUrl}"); - } + var user = optimizelyClient.CreateUserContext(USER_ID); + // Fetch + // Console.WriteLine("Fetch:" + user.FetchQualifiedSegments()); + // var qualifiedSegments = user.GetQualifiedSegments(); + // Console.WriteLine(JsonConvert.SerializeObject(qualifiedSegments)); + // const string SEGMENT_ID = "atsbugbashsegmentdob"; + // Console.WriteLine($"Is Qualified for {SEGMENT_ID}: {user.IsQualifiedFor(SEGMENT_ID)}"); + + // TrackEvent + // user.TrackEvent("myevent"); + + // Decide + // var decision = user.Decide("flag1"); + // Console.WriteLine(JsonConvert.SerializeObject(decision)); + // var variables = decision.Variables.ToDictionary(); + // Console.WriteLine(JsonConvert.SerializeObject(variables)); + + // DecideForKeys + var keys = new[] {"flag1", "flag2"}; + var decisions = user.DecideForKeys(keys); + Console.WriteLine(JsonConvert.SerializeObject(decisions)); + + // DecideAll + // var decisions = user.DecideAll(); + // Console.WriteLine(JsonConvert.SerializeObject(decisions)); + + // Set & Get & Remove ForcedDecision + // var context = new OptimizelyDecisionContext("flag1", "default-rollout-34902-22583870382"); + // var forcedDecision = new OptimizelyForcedDecision("off"); + // user.SetForcedDecision(context, forcedDecision); + // var result = user.GetForcedDecision(context); + // Console.WriteLine(JsonConvert.SerializeObject(result)); + // var wasRemoved = user.RemoveForcedDecision(context); + // Console.WriteLine($"Was removed: {wasRemoved}"); + + // Activate + // var variation = optimizelyClient.Activate("flag1", USER_ID); + // Console.WriteLine("Variation: " + JsonConvert.SerializeObject(variation)); + optimizelyClient.Dispose(); } } diff --git a/QuickStart/QuickStart.csproj b/QuickStart/QuickStart.csproj index 31cf1bcc..235f71cc 100644 --- a/QuickStart/QuickStart.csproj +++ b/QuickStart/QuickStart.csproj @@ -34,6 +34,9 @@ 4 + + ..\packages\Newtonsoft.Json.13.0.2\lib\net45\Newtonsoft.Json.dll + @@ -49,6 +52,10 @@ OptimizelySDK + + + +