1

I'm trying to integrate LaunchDarkly into my project. I'm seeing a problem where the LdClient connects in one version and doesn't in another. The code is essentially identical. I got their example running via a simple Console app in .NET Framework 4.8 using the Server SDK. You can find a version of it here. This is what my working project looks like:

using System;
using System.Net.Sockets;
using System.Runtime.Remoting.Contexts;
using LaunchDarkly.Sdk;
using LaunchDarkly.Sdk.Server;
using Context = LaunchDarkly.Sdk.Context;
namespace HelloDotNet
{
    class Program
    {
        // Set SdkKey to your LaunchDarkly SDK key.
        public const string SdkKey = "my-sdk-key";
        // Set FeatureFlagKey to the feature flag key you want to evaluate.
        public const string FeatureFlagKey = "my-flag";
        private static void ShowMessage(string s)
        {
            Console.WriteLine("*** " + s);
            Console.WriteLine();
        }
        static void Main(string[] args)
        {
            var ldConfig = Configuration.Default(SdkKey);
            var client = new LdClient(ldConfig);
            if (client.Initialized)
            {
                ShowMessage("SDK successfully initialized!");
            }
            else
            {
                ShowMessage("SDK failed to initialize");
                Environment.Exit(1);
            }
            // Set up the evaluation context. This context should appear on your LaunchDarkly contexts
            // dashboard soon after you run the demo.
            var context = Context.Builder("test")
                .Name("Sandy")
                .Build();
            var flagValue = client.BoolVariation(FeatureFlagKey, context, false);
            ShowMessage(string.Format("Feature flag '{0}' is {1} for this context",
                FeatureFlagKey, flagValue));
            // Here we ensure that the SDK shuts down cleanly and has a chance to deliver analytics
            // events to LaunchDarkly before the program exits. If analytics events are not delivered,
            // the context attributes and flag usage statistics will not appear on your dashboard. In
            // a normal long-running application, the SDK would continue running and events would be
            // delivered automatically in the background.
            client.Dispose();

            Console.ReadKey();
        }
    }
}

However, if I then transfer that code to just a class in a ClassLibrary, the LdClient never connects and client.Initalized is always false. In turn, this means I can never see my flags toggle. For example, the client in this Singleton never connects:

using LaunchDarkly.Sdk.Server;
using System;
using LaunchDarkly.Sdk;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using Context = LaunchDarkly.Sdk.Context;

namespace FeatureFlags
{ 
    public class FeatureFlagsManager
    {
        //Load from something better in the future, hardcoded for now
        private readonly string _sdkKey = "my-sdk-key";
        private Configuration _ldConfig;
        private LdClient _ldClient;
        private Context _context;
        private static readonly Lazy<FeatureFlagsManager> lazy = new Lazy<FeatureFlagsManager>(() => new FeatureFlagsManager());
        public static FeatureFlagsManager Instance => lazy.Value;

        private FeatureFlagsManager()
        {
            _ldConfig = Configuration.Default(_sdkKey);
            _ldClient = new LdClient(_ldConfig);

            //load key and name from something in the future
            _context = Context.Builder("test").Name("Sandy").Build();
        }

        public bool GetFeatureFlagBool(string featureFlagKey)
        {
            bool enabled = _ldClient.BoolVariation(featureFlagKey, _context, false);
            return enabled;
        }
    }
}

I also observe that if I turn the first, working example into a class library and put the contents of main into a method and try to run the method, the client does not initialize.

2 Answers 2

2

EDIT: I found the following by noticing Launch Darkly was logging errors in the compiler console.Specifically, 2024-04-12 15:45:13.829 -05:00 [LaunchDarkly.Sdk.DataSource] ERROR: Unexpected error in stream processing: System.IO.FileLoadException: Could not load file or assembly 'System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

I finally got it working. High level:

  1. Use fuslogvw.exe to view binding errors. Saw native images threw error also.
  2. Use ngen.exe update to update native images.
  3. Added the binding redirect from my app.config to machine.config for .net framework.

How to run fuslogvw.exe and ngen.exe VisualStudio in admin mode. Tools>>Command Line>>Developer Command Prompt

fuslogvw.exe In the GUI, Settings>>Log bind failures to disk and Enable Custom log path. Enter desired directory.

In the Developer Command Prompt: ngen.exe update or ngen.exe /? to see what options you have to you.

You can use this to find machine.config: Where Is Machine.Config?

Modified runtime to have this:

  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
Sign up to request clarification or add additional context in comments.

Comments

1

I had the same issue. After much gnashing of teeth, it turned out to be a bug in the latest version and specific to .NET Framework 4.8. I downgraded my NuGet package to 7.1.0 and it worked again.

I submitted this issue to LaunchDarkly.

https://github.com/launchdarkly/dotnet-server-sdk/issues/184

Hope this helps!

2 Comments

Thanks; gave it a shot but if I start with a fresh project and install the 7.1.0 Server.SDK I keep getting a System.IO.FileLoadException where it says it cannot load LaunchDarkly.Logging, Version=1.0.1.0 or one of it's dependencies. 7.1.0 installs Logging 2.0.0 by default, and the exception is being thrown originally at LaunchDarkly.Sdk.Server.Internal.DataSources.StreamingDataSource.CreateEventSource. Downgrading the package to 1.0.1.0 seems to change some of the namespace strucuting too.
You may want to try the below solution I found so you don't have to downgrade. I was able to figure this out after looking at the output provided by the visual studio compiler and spending a few hours playing with things

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.