4

I use this contract resolver for dependency-injection with Autofac and Json.NET:

public class AutofacContractResolver : DefaultContractResolver
{
    private readonly IComponentContext _container;

    public AutofacContractResolver(IComponentContext context)
    {
        _container = context ?? throw new ArgumentNullException(nameof(context));
    }

    protected override JsonObjectContract CreateObjectContract(Type objectType)
    {
        var contract = base.CreateObjectContract(objectType);

        // use Autofac to create types that have been registered with it
        if (_container.IsRegistered(objectType))
        {
            contract.DefaultCreator = () => _container.Resolve(objectType);
        }

        return contract;
    }
}

Then, I use it with DI to initialize the JsonSerializer:

var contractResolver = ctx.Resolve<IContractResolver>(); // ctx = Autofac's IComponentContext

var jsonSerializer = new JsonSerializer
{
    ContractResolver = contractResolver, // <-- AutofacContractResolver 
};


What would be the equivalent of this technique with the new System.Text.Json in net-core-3.0 - if there is any already? I wasn't able to figure this out and couldn't find any interfaces that would look similar to this ones.

4

1 回答 1

1

请尝试我作为 System.Text.Json 的扩展编写的这个库,以提供缺少的功能:https ://github.com/dahomey-technologies/Dahomey.Json 。

您会发现对编程对象映射的支持。

定义自己的 IObjectMappingConvention 实现:

public class AutofacObjectMappingConvention : IObjectMappingConvention
{
    private readonly IComponentContext _container;

    public AutofacObjectMappingConvention(IComponentContext context)
    {
        _container = context ?? throw new ArgumentNullException(nameof(context));
    }


    public void Apply<T>(JsonSerializerOptions options, ObjectMapping<T> objectMapping) where T : class
    {
        defaultObjectMappingConvention.Apply<T>(options, objectMapping);

        // use Autofac to create types that have been registered with it
        if (_container.IsRegistered(objectType))
        {
            objectMapping.MapCreator(o => _container.Resolve<T>());
        }
    }
}

实现 IObjectMappingConventionProvider 以将多个类型与约定相关联:

public class AutofacObjectMappingConventionProvider : IObjectMappingConventionProvider
{
    public IObjectMappingConvention GetConvention(Type type)
    {
        // here you could filter which type should be instantiated by autofac and return null for other types
        return new AutofacObjectMappingConvention();
    }
}

通过调用命名空间 Dahomey.Json 中定义的扩展方法 SetupExtensions 调用 JsonSerializerOptions 来设置 json 扩展:

JsonSerializerOptions options = new JsonSerializerOptions();
options.SetupExtensions();

为类注册新的对象映射约定:

options.GetObjectMappingConventionRegistry().RegisterProvider(new AutofacObjectMappingConventionProvider());

然后使用常规的 Sytem.Text.Json API 序列化您的类:

string json = JsonSerializer.Serialize(myClass, options);
于 2019-12-11T22:14:57.340 回答