Restrict custom TypeConverter to a specific assembly

420 views Asked by At

I have defined a custom TypeConverter and associated custom TypeDescriptionProvider and TypeDescriptor so that my types are converted automatically to strings when returning values from a REST web service (using ASP.NET Core).

However, I now notice that in other places in my application (e.g. when I am serializing XML saving my config files, or loading XAML in WPF) that my custom TypeConverter is being called.

Is there a way of restricting my custom type converter / description provider / descriptor so that they are only used in my Web service assembly?


More info

My internal objects are not using [TypeConverter()] attributes to specify a type converter to use.

I am using AutoMapper to do my mapping from my internal objects to data transfer objects, as an answer suggests. It is AutoMapper that makes use of the TypeDescriptor/TypeConverter, to map properties of my objects to strings automatically. I want the behavior to be so that only AutoMapper uses this custom type converter.

However, type converters appear to be registered globally: TypeDescriptor.AddProvider(customerProvider, myType)

I cannot see a way of restricting this to just certain components. My only ideas so far are somehow using the GetComponentName() of the ICustomTypeDescriptor (but this appears always to be null) or running my Web server in a separate AppDomain, which I assume uses separate type converters, but would likely bring huge problems with marshalling/serialization. Is there another solution?

1

There are 1 answers

1
Dongdong On BEST ANSWER

Once attributes are hard coded on your models, then it will be hard to change/modify/disable at runtime, and impossible to remove. in your case, even in web application, you cannot disable or remove those attributes.

I give you an option, AutoMapper, I've been using it to do converting jobs for years, especially for MVXX pattern, no matter ASP.NET MVC or WPF MVVM, both of them need convert view models to real models. AutoMapper applies converter by configuration, but not attributes, which make your request possible.

https://github.com/AutoMapper/AutoMapper/blob/master/docs/Custom-type-converters.md

Mapper.Initialize(cfg => {
  cfg.CreateMap<ModelA, string>().ConvertUsing(new ModelAToStringTypeConverter());
  cfg.CreateMap<ModelA, ModelB>().ConvertUsing(new ModelAToBTypeConverter());
  cfg.CreateMap<ModelB, ModelA>().ConvertUsing(new ModelBToATypeConverter());
  ....
  cfg.AddProfile<WpfProfile>();
});

public class WpfProfile: Profile
{
    public OrganizationProfile()
    {
        CreateMap<Foo, FooDto>();
        // Use CreateMap... Etc.. here (Profile methods are the same as configuration methods)
    }
}

if properties of ModelA is a subset of ModelB, you don't even to hard code your converter, cfg.CreateMap<ModelB, ModelA>() will do the magic automatically.

AutoMapper mention this:

The .NET Framework also supports the concepts of type converters, through the TypeConverter class. AutoMapper supports these types of type converters, in configuration checking and mapping, without the need for any manual configuration. AutoMapper uses the TypeDescriptor.GetConverter method for determining if the source/destination type pair can be mapped.