Skip to content

[Mapster Tool] Add support for global:: to disambiguate type names in generated mappers #1020

Open

Description

@BladeWise

In some cases it could be useful to generate sources where type names are fully qualified with global:: prefix.

If the mapper class is generated in a namespace that partially collides with the one where models are defined, compilation fails.
An example:

namespace Company.Models
{
    public class MyModel
    {
    }
}

namespace ThirdParty.Models
{
    public class OtherModel
    {
    }
}

namespace Prefix.Company.Mappers
{
    using ThirdParty.Models;
    using Company.Models;

    public partial class Mapper
    {
        MyModel Map(OtherModel model);
    }
}

In this case the compiler will trigger a CS0234
The type or namespace 'Models' does not exist in the namespace 'Prefix.Company' (are you missing an assembly reference?)
due to the standard namespace resolution strategy of the compiler.
Even qualifying the name like this

namespace Prefix.Company.Mappers
{
    using ThirdParty.Models;

    public partial class Mapper
    {
        Company.Models.MyModel Map(OtherModel model);
    }
}

does not fix the error, and the only proper fix is to use the global:: qualifier

namespace Prefix.Company.Mappers
{
    using ThirdParty.Models;
    // The following is equivalent to inline global qualificatio
    // using global::Company.Models;

    public partial class Mapper
    {
        global::Company.Models.MyModel Map(OtherModel model);
    }
}

The Mapster tool allows to generate mappers with a fully qualified name, but it does not prefix types with global:: (neither provides an option to do so).
It would be nice if such feature was added.
I am willing to provide a PR eventually.

Activity

  1. DocSvartz commented on Sep 16, 2026

    @DocSvartz
    Contributor

    Hi @BladeWise.
    With which Mapster Tool settings does the generation of using statements occur after the namespace declaration?

    This looks more like some kind of output sequence bug 🤔

    The standard behavior is as follows:

    // generated file
    
    using ThirdParty.Models;
    using Company.Models;
    
    namespace Prefix.Company.Mappers
    {
        
        public partial class Mapper
        {
            MyModel Map(OtherModel model);
        }
    }
    
    // end generated file
    
  2. BladeWise commented on Sep 17, 2026

    @BladeWise
    Author

    My example was probably misleading due to my linter moving usings inside the namespace (which changes the namespace resolution rules), but the problem is with the -p option which generates namespace-qualified type names.

    Attached is a solution with a repro project.
    What happens is that without -p Mapster generates this (as you said)

    using Company.Models;
    using Prefix.Company;
    using ThirdParty.Models;
    
    namespace Prefix.Company
    {
        public partial class MyMapper : IMyMapper
        {
            public MyModel Map(OtherModel p1)
            {
                return p1 == null ? null : new MyModel() {Id = p1.Id};
            }
        }
    }

    which compiles fine, but using -p it generats this

    namespace Prefix.Company
    {
        public partial class MyMapper : Prefix.Company.IMyMapper
        {
            public Company.Models.MyModel Map(ThirdParty.Models.OtherModel p1)
            {
                return p1 == null ? null : new Company.Models.MyModel() {Id = p1.Id};
            }
        }
    }

    which exhibits the problem

    The type or namespace name 'Models' does not exist in the namespace 'Prefix.Company' (are you missing an assembly reference?)
    

    The simpler fix would be to include a global:: prefix to the namespace-qualified type names (which is quite common in generators to avoid namespace resolution issues)

    namespace Prefix.Company
    {
        public partial class MyMapper : global::Prefix.Company.IMyMapper
        {
            public global::Company.Models.MyModel Map(global::ThirdParty.Models.OtherModel p1)
            {
                return p1 == null ? null : new global::Company.Models.MyModel() {Id = p1.Id};
            }
        }
    }

    eventually, enabling this behavior with a dedicated switch.

    Sorry for the misleading sample in my first post!

  3. DocSvartz commented on Sep 17, 2026

    @DocSvartz
    Contributor

    @andrerav @stagep
    I think this can be done as a default behavior when generation using the -p option.
    If this doesn’t cause problems when using aliases. (need tests)

    What are your think about this?

  4. DocSvartz commented on Oct 21, 2026

    @DocSvartz
    Contributor

    Hi, @BladeWise In the pre-release version 10.0.14-pre01,
    the -p option generates types using the global:: prefix.

  5. BladeWise commented on Oct 21, 2026

    @BladeWise
    Author

    Thanks a lot for the fix!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions