I have lots of json converters, which derive from JsonConverter<T>
. They are in various assemblies, not just the executing assembly.
I register them like this:
services
.AddControllers()
.AddJsonOptions(o => {
o.JsonSerializerOptions.Converters.Add(new FooJsonConverter());
o.JsonSerializerOptions.Converters.Add(new BarJsonConverter());
o.JsonSerializerOptions.Converters.Add(new BazJsonConverter());
o.JsonSerializerOptions.Converters.Add(new QuxJsonConverter());
// lots more...
});
I'd rather add them dynamically, using an assembly scan - the same way AutoMapper, FluentValidation, Autofac, etc., do it. I looked at their repos for the secret sauce but couldn't find it.
So I tried some basic reflection:
services
.AddControllers()
.AddJsonOptions(o => {
var jsonConverters =
AppDomain.CurrentDomain
.GetAssemblies()
.SelectMany(x => x.ExportedTypes)
.Where(x => x.BaseType != null && x.IsAssignableFrom(typeof(JsonConverter<>)));
foreach (var jsonConverter in jsonConverters)
o.JsonSerializerOptions.Converters.Add(Activator.CreateInstance(jsonConverter) as JsonConverter);
});
But that fails to start, and throws:
FTL | Microsoft.AspNetCore.Hosting.Diagnostics | Application startup exception
Autofac.Core.DependencyResolutionException: An exception was thrown while activating Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionEndpointDataSourceFactory -> Microsoft.AspNetCore .Mvc.Infrastructure.DefaultActionDescriptorCollectionProvider -> λ:Microsoft.AspNetCore.Mvc.Abstractions.IActionDescriptorProvider[] -> Microsoft.AspNetCore.Mvc.ApplicationModels.ControllerA ctionDescriptorProvider -> Microsoft.AspNetCore.Mvc.ApplicationModels.ApplicationModelFactory -> λ:Microsoft.AspNetCore.Mvc.ApplicationModels.IApplicationModelProvider[] -> Microsoft.AspNetC ore.Mvc.ApplicationModels.DefaultApplicationModelProvider -> Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.DefaultModelMetadataProvider -> λ:Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.I CompositeMetadataDetailsProvider.
---> System.MissingMethodException: Cannot create an abstract class.
at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean wrapExceptions, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& hasNoDefaultCtor )
Note the Cannot create an abstract class
. The base class is abstract, but I'm trying to activate the subclasses.
What is the correct way to do this? Also, is it appropriate to refer to the AppDomain, as I remember reading somewhere that that behavior has changed in aspnet.
Aucun commentaire:
Enregistrer un commentaire