为Nancy注册一个使用NancyContext的序列化程序

本文关键字:NancyContext 程序 序列化 一个 注册 Nancy | 更新日期: 2023-09-27 18:01:11

我想对Nancy模块使用自定义序列化,它使用请求的URL作为输入的一部分。

我已经看到,您需要在ConfigureRequestContainer的覆盖中注册使用上下文的依赖项(如C#IOC和NancyFX中的Request State中所回答的(

public class NancyBootstrapper : DefaultNancyBootstrapper
{
    protected override void ConfigureRequestContainer(
        TinyIoCContainer container, 
        NancyContext context)
    {
        container.Register<JsonSerializer>(new CustomJsonSerializer(context));
    }
}

我已经看到,您可以使用IRegistrations接口为Nancy指定不同的串行器(如使用Nancy TinyoC配置JsonNetSerializer和JsonNetBodyDeserializer中的回答(

public class JsonRegistration : IRegistrations
{
    public IEnumerable<TypeRegistration> TypeRegistrations
    {
        get
        {
           yield return new TypeRegistration(typeof(JsonSerializer), typeof(CustomJsonSerializer));
        }
    }
    public IEnumerable<CollectionTypeRegistration> CollectionTypeRegistrations { get; protected set; }
    public IEnumerable<InstanceRegistration> InstanceRegistrations { get; protected set; }
}

如果我以第一种方式注册序列化程序,我就无法让Nancy将其用于JSON序列化。

如果我以第二种方式注册它,我就无法注入当前NancyContext的副本并访问该请求——它试图在调用ConfigureRequestContainer方法之前创建serializer的实例。

我在这里错过了什么?

为Nancy注册一个使用NancyContext的序列化程序

假设您对"序列化"部分感兴趣,即将模型返回为json,您是否考虑扩展模型以通过管道携带所需信息,然后由序列化程序剥离它?

以下代码假设自定义序列化程序足够智能,不会序列化null属性。

Get["/somedata"] = _ => new MyModelEx
   { 
      WhateverRealProperty = "some data",
      RequestUri = this.Context.Request.Uri
   };
public class MyModelEx : MyModel, IModelWithRequestUri
{
    public string RequestUri {get; set;}
}

在你的序列化程序中,你可以测试这个"额外"的数据元素,从中获取你需要的任何东西,将其剥离(设置为null??(,并序列化其余的

或者上面的变体,在那里你可以有一些"容器"通用模型,比如

public class ExtendedModel<T>
{
    public T Model {get; set;}
    public string RequestUri {get;set;} // or even pass the whole context if u need to
}

上面的一些变体将是最简单的实现。

我更喜欢一种不同的方法,在这种方法中,我会创建某种形式的每个请求的"包",在其中保存当前上下文,并将该包注入序列化程序(当然,这也需要每个请求注册序列化程序(。

请检查此答案以了解想法。