8

私はナンシーの初心者です。REST API を作成するためのフレームワークとして使用しています。私は Json.NET に精通しているので、Nancy.Serialization.JsonNetパッケージで遊んでいます。

私の目標: と の動作をカスタマイズする (つまり、設定を変更する) ことJsonNetSerializerですJsonNetBodyDeserializer

具体的には以下の設定を取り入れたい...

var settings = new JsonSerializerSettings { Formatting = Formatting.Indented };
settings.Converters.Add( new StringEnumConverter { AllowIntegerValues = false, CamelCaseText = true } );

組み込みの TinyIoC コンテナーを使用してこのカスタマイズを実行し、継承チェーンを回避して、Nancy.Serialization.JsonNetパッケージの変更によって発生する可能性のある問題を制限したいと考えました。

注: 一時的な回避策として、継承を利用して と を作成CustomJsonNetSerializerCustomJsonNetBodyDeserializerました。

この構成を組み込むために、少なくともJsonNetSerializer. JsonNetBodyDeserializerTinyIoC を使用しての構成はまだ試していません。同様に行われると思います。私が試したすべての作業は私のものですCustomNancyBootstrapper(から継承していDefaultNancyBootstrapperます)。

これまでで最も成功したアプローチ: オーバーライドConfigureApplicationContainer

protected override void ConfigureApplicationContainer( TinyIoCContainer container )
{
    base.ConfigureApplicationContainer( container );

    // probably don't need both registrations, and I've tried only keeping one or the other
    var settings = new JsonSerializerSettings { Formatting = Formatting.Indented };
    settings.Converters.Add( new StringEnumConverter { AllowIntegerValues = false, CamelCaseText = true } );
    container.Register( new JsonNetSerializer( JsonSerializer.CreateDefault( settings ) ) );
    container.Register<ISerializer>( new JsonNetSerializer( JsonSerializer.CreateDefault( settings ) ) );
}

コードをトレースJsonNetSerializer(JsonSerializer serializer)し、JsonNet パッケージのコンストラクターを確認しました。

潜在的な問題: コンストラクターが 2 回呼び出されていることに気付きました。この動作は予期していませんでした。

初めてすべてが適切です-私のカスタマイズが追加され、適切に登録されます。ただし、2 回目は、設定のカスタマイズなしでタイプが再登録されます。再登録は、設定のカスタマイズを失った元の登録を置き換えるように見えます。

コンストラクターが2回目に呼び出されたときのコールスタックは、コンストラクターが呼び出され、構築しようとしているように見えることをGetEngine示しています(私はセルフホストパッケージを使用しているため、これはprogram.csで発生します- )。GetEngineInternalNancyEngineusing(var host = new NancyHost(uri))

ナンシーに何もしないように伝えるか、チェーンの後半部分に接続する必要があるようです。

どんな助けでも大歓迎です。

4

1 に答える 1

16

通常、ナンシーでこれを解決する方法は、次のように独自の JSON シリアライザーを実装することです。

public sealed class CustomJsonSerializer : JsonSerializer
{
    public CustomJsonSerializer()
    {
        ContractResolver = new CamelCasePropertyNamesContractResolver();
        Converters.Add(new StringEnumConverter
        {
            AllowIntegerValues = false, 
            CamelCaseText = true
        });
        Formatting = Formatting.Indented;
    }
}

ここで、すべての設定を上書きできます。

次に、それを登録できます。私はこれを使用して行いますIRegistrations

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; }
}

Q: このアプローチは、JsonNetSerializer を継承して CustomJsonNetSerializer を作成し、それを ConfigureApplicationContainer (container.Register( typeof(JsonNetSerializer), typeof(CustomJsonNetSerializer) ) ) に登録することとどのように異なりますか?

A: JsonSerializer は、Nancy の json.net の場合の実装です。これは、github の readme で定義されている推奨メソッドです。

https://github.com/NancyFx/Nancy.Serialization.JsonNet#customization

あなたが言及したクラスはJSONへのオブジェクトのシリアル化です。逆シリアル化を処理する別のクラスがあり、どちらもJsonSerializerを内部的に利用しています:

https://github.com/NancyFx/Nancy.Serialization.JsonNet/blob/master/src/Nancy.Serialization.JsonNet/JsonNetSerializer.cs#L10

このメソッドを使用すると、JsonSerializer が使用されるすべての場所で実装設定の一貫性が保たれます。

Q: 概説したアプローチから、CustomNancyBootstrapper の ConfigureApplicationContainer オーバーライドで CustomJsonSerializer を明示的に登録する必要がなくなることを正しく推測できますか?

A: 私が登録のために行った方法は、依存関係を登録するための単純な抽象化です。1 つの巨大な Bootstrapper を作成するのではなく、いくつかの小さな特定のクラスを作成できます。

はい、私の方法を使用すると、ブートストラップに登録する必要はありません。

于 2014-07-22T07:24:38.433 に答える