Mark Beussink
Mark Beussink

Reputation: 33

Avoiding or fixing namespace pollution in .Net Core

Summary

For my CS capstone project we are encountering an issue with a class name existing in two different dependencies. Specifically, we are using a dependency for using MySQL with Entity Frame and one for just connected and executing MySQL queries directly.

Background

The non-EF is owned by a component outside of the project, and this database is one of our main ways of interacting with the database. It has been requested by the client/mentor that any additions or changes we need be made to a separate database, which is the database EF is connecting to.

The question

My question is essentially about how do I fix error the type <class-name> exists in both..., but I'm more wondering about the root problem of namespace pollution in .Net Core and the courses of action we can take. I have looked into the error and the initial results described a fix that is only applicable in .Net not .Net Core and an explanation that .Net Core does not support aliasing.

Potential fixes

using System;
using System.Collections.Generic;
using MySql.Data.MySqlClient;

namespace OVD.API.GuacamoleDatabaseConnectors
{
    public class GuacamoleDatabaseConnector : IDisposable
    {

        private MySqlConnection connection;
...

The error is on the MySqlConnection type and is, in full: GuacamoleDatabaseConnectors/GuacamoleDatabaseConnector.cs(81,16): error CS0433: The type 'MySqlConnection' exists in both 'MySql.Data, Version=8.0.15.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d' and 'MySqlConnector, Version=0.49.2.0, Culture=neutral, PublicKeyToken=d33d3e53aa5f8c92' [/Users/markbeussink/Action/OVD/OVD.API/OVD.API.csproj]

Here is the .cs.proj

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.App"/>
    <PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All"/>
    <PackageReference Include="Ldap.NETStandard" Version="1.0.3"/>
    <PackageReference Include="MySql.Data" Version="8.0.15"/>
    <PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="2.2.0"/>
  </ItemGroup>
</Project>

Upvotes: 3

Views: 517

Answers (2)

David Browne - Microsoft
David Browne - Microsoft

Reputation: 89434

It's really bad form for two separate projects to have a type with the same namespace and the same name, for the reason you've just discovered. It is not at all normal or expected that you would run into such a conflict, and you may well never encounter it again in your career.

It looks like this project:

https://www.nuget.org/packages/MySqlConnector/

decided to clobber the namespace of the more official ADO.NET provider for MySQL:

https://www.nuget.org/packages/MySql.Data

by defining a type called: MySql.Data.MySqlClient.MySqlConnection, instead of using MySqlConnector.MySqlClient.MySqlConnection, or somesuch.

The best way forward is to exclude one of these from your projects, and use just the other. Here the obvious choice would be to switch from

https://www.nuget.org/packages/Pomelo.EntityFrameworkCore.MySql/

to

https://www.nuget.org/packages/MySql.Data.EntityFrameworkCore/

But I don't have any opinion on the relative merits of these libraries.

If you can't do this, C# provides a compiler directive for you to alias one of the assemblies with a different namespace. See https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-messages/cs0433

This will in effect add a new outermost namespace level to the offending assembly, so the other MySqlConnection would be known (only in your code) as SomeAlias.MySql.Data.MySqlClient.MySqlConnection.

Upvotes: 0

Pawlinski
Pawlinski

Reputation: 46

Just create a new project "class library" and inside this project, you can create an interface which gives you access to a method from one of your component (you need to implement your "component" and its method inside this project). Something like in facade pattern. Then in the rest of your solution, you will use a newly created project reference only. This solution allows you define your own namespace name

Upvotes: 2

Related Questions