Visual Studio Community (Mac) problems with Configuration / Startup: TypeLoadException

We have the following code:

            var couchbaseConfiguration =
                (CouchbaseClientSection) ConfigurationManager.GetSection(configurationSectionName);
                couchbaseClientConfiguration = new ClientConfiguration(couchbaseConfiguration);

This code works fine on Windows however, in Visual Studio Community, it does not. It throws a TypeLoadException when trying to figure out what Serializer, Converter, and Transcoder are. What is going on in ClientConfiguration.cs here https://github.com/couchbase/couchbase-net-client/blob/release27/Src/Couchbase/Configuration/Client/ClientConfiguration.cs#L302-L311:

            //transcoders, converters, and serializers...o mai.
            Serializer = definition.Serializer != null
                ? SerializerFactory.GetSerializer(definition.Serializer)
                : SerializerFactory.GetSerializer();
            Converter = definition.Converter != null
                ? ConverterFactory.GetConverter(definition.Converter)
                : ConverterFactory.GetConverter();
            Transcoder = definition.Transcoder != null
                ? TranscoderFactory.GetTranscoder(this, definition.Transcoder)
                : TranscoderFactory.GetTranscoder(this);

The defintion.X all wind up coming out in the debugger as undefined.

I have a workaround:

           try
            {
                couchbaseClientConfiguration = new ClientConfiguration(couchbaseConfiguration)
                {
                    Servers = alteredServers
                };
            }
            catch (TypeLoadException e)
            {
                // Workaround for Visual Studio Community / Mac that doesn't process these correctly

                // When the name and type are empty, under the covers the ClientConfiguration 

                if ((couchbaseConfiguration.Serializer.Name == "") && (couchbaseConfiguration.Serializer.Type == ""))
                {
                    couchbaseConfiguration.Serializer = new SerializerElement();
                }

                if ((couchbaseConfiguration.Converter.Name == "") && (couchbaseConfiguration.Converter.Type == ""))
                {
                    couchbaseConfiguration.Converter = new ConverterElement();
                }

                if ((couchbaseConfiguration.Transcoder.Name == "") && (couchbaseConfiguration.Transcoder.Type == ""))
                {
                    couchbaseConfiguration.Transcoder = new TranscoderElement();
                }

                couchbaseClientConfiguration = new ClientConfiguration(couchbaseConfiguration)
                {
                    Servers = alteredServers
                };
            }

EDIT: even though this seems to work, it looks like I cannot connect to a bucket…

Complains: “Could not bootstrap with CCCP. (Could not find: )” I think this is related to the connection pool not initializing…

Then Complains: {Couchbase.Configuration.CouchbaseBootstrapException: After bootstrapping the nodes list has zero elements indicating that client failed during bootstrapping. Please check the client logs for more information as for why it failed. at Couchbase.Configuration.C…}

Hi @unhuman -

This is one of the drawbacks of .NET Core; every platform has a different implementation or lack there of in this case! This is really common for System.Configuration stuff it seems. I am not sure what what version of core you are using, but a newer vesion may resolve it.

In this case you’ll have to look into the logs and determine why the client could not connect to the server and then handle accordingly.

-Jeff

I came up with a functional workaround. It’s not amazing, but…

            var parasiteConfig = (CouchbaseClientSection)ConfigurationManager.GetSection(configurationSectionName);
            if ((parasiteConfig.Serializer.Name == "") && (parasiteConfig.Serializer.Type == ""))
            {
                parasiteConfig.Serializer = new SerializerElement();
            }

            if ((parasiteConfig.Converter.Name == "") && (parasiteConfig.Converter.Type == ""))
            {
                parasiteConfig.Converter = new ConverterElement();
            }

            if ((parasiteConfig.Transcoder.Name == "") && (parasiteConfig.Transcoder.Type == ""))
            {
                parasiteConfig.Transcoder = new TranscoderElement();
            }

            var parasiteClientConfiguration = new ClientConfiguration(parasiteConfig)
            {
                Servers = replacementServers
            };


            // Now generate a new configuration (from scratch) and we'll swap in bits from the defective configuration above
            var couchbaseConfiguration = (CouchbaseClientSection)ConfigurationManager.GetSection(configurationSectionName);

            var clientConfig = new ClientConfiguration
            {
                Servers = parasiteClientConfiguration.Servers,
                BucketConfigs = parasiteClientConfiguration.BucketConfigs,
                // make sure we use a valid Serializer
                Serializer = ((couchbaseConfiguration.Serializer.Name == "") && (couchbaseConfiguration.Serializer.Type == ""))
                            ? () =>
                                    {
                                        JsonSerializerSettings serializerSettings = new JsonSerializerSettings()
                                        {
                                            ContractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver()
                                        };

                                        return new DefaultSerializer(serializerSettings, serializerSettings);
                                    }
                            : parasiteClientConfiguration.Serializer,
                ForceSaslPlain = parasiteClientConfiguration.ForceSaslPlain
            };

            return clientConfig;