私は現在、必要に応じて WebAPI/WFC/etc 経由で渡したいビジネス オブジェクトのカスタム ライブラリを利用しているプロジェクトを持っています。私が到達しているハードルの 1 つは、WebAPI を介してオブジェクトの逆シリアル化を処理することです。
オブジェクト自体は Factory パターンに準拠しているため、パラメーターなしのパブリック コンストラクターはなく (保護されているとマークされています)、Factory を使用してオブジェクトのインスタンスを作成します。これにはいくつかの重要な理由がありますが、中間クラス/モデルを作成する必要なくオブジェクトを使用できるようにしたいと考えています。
このため、モデルがバインドされている場合、WebAPI フレームワークはオブジェクトのインスタンスの作成に失敗し、「パラメーターなしのコンストラクターがありません」というエラーが発生します。ファクトリ メソッドを呼び出して、新しいオブジェクトをフォーマッタまたはバインダー (または逆シリアル化プロセスの一部である何か) に返す方法を見つける必要があります。
その上に別のフレームワークを実装することなく、この状況を処理するために Web API を拡張する方法に関する明確な方法 (およびドキュメント) はありますか? ご協力いただければ幸いです。
編集: 新しいモデル バインダーを作成し、BindModel() のファクトリ クラスを介してオブジェクトを作成しました。オブジェクトを bindingContext.Model に割り当て、オブジェクトを手動で逆シリアル化するだけで、必要なことを達成できましたが、100% 正しい方法かどうかはわかりません。
私のコードについては以下を参照してください。
Public Class FactoryModelBinder
Implements IModelBinder
Public Function MindModel(actionContext as HttpActionContext, bindingContext as ModelBindingContext) As Boolean Implements IModelBinder.BindModel
Dim type = bindingModel.ModelType
Dim attributes = type.GetCustomAttributes(FactoryAttribute, False)
If attributes.Length > 0 Then
Dim factoryAttribute As FactoryAttribute = DirectCast(attributes(0), FactoryAttribute)
bindingContext.Model = factoryAttribute.FactoryType.InvokeMember("Create", BindingFlags.InokveMethod Or BindingFlags.Public Or BindingFlags.Static, Nothing, Nothing, Nothing)
Dim data as FormDataCollection = New FormDataCollection(actionContext.Request.Content.ReadAsStringAsync().Result)
Dim dict as NameValueCollection = data.ReadAsNameValueCollection()
For Each item as String in dict.Keys
Dim pi as PropertyInfo = bindingContext.Model.GetType().GetProperty(item)
pi.SetValue(bindingContext.Model, dict(item), Nothing)
Next
Return True
End If
Return False
End Function
このコードは、Create() メソッドの呼び出しに使用できるように、オブジェクト クラスで Factory の Type を指定するカスタム属性 (FactoryAttribute) に依存しています。
これに関するご意見をお待ちしております。