ご意見をもとに、私はここに私の答えを修正:)
ModelStateDictionary
明確にコンテナによって解決されるべきサービスではなく、むしろデータいるはずインスタンス化時に提供されます。 ModelStateが各コントローラインスタンスによって所有されているため、「解決時」にコンテナが利用できないという事実から、これを知ることができます。
はさらに、各ModelValidation
インスタンスはModelStateDictionary
インスタンスにバインドされ、ひいてはデータとして考えられるべきです。
Autofacでは、データをコンストラクタに渡す必要がある場合(任意で他の依存関係に加えて)、ファクトリデリゲートを使用する必要があります。これらの代理人は、依存関係とコンストラクタに渡すデータを処理します。 Autofacの魅力的なことは、これらの代理人を自動生成できることです。
は、私は以下のソリューションを提案:ModelValidationとたCustomerServiceの両方が彼らのコンストラクタ内のデータを必要とするので
、我々は2人の工場の代表者(注:パラメータ名は、対応するコンストラクタ内の名前と一致する必要があります):必要
public delegate IModelValidation ModelValidationFactory(ModelStateDictionary msd);
public delegate CustomerService CustomerServiceFactory(ModelStateDictionary msd);
これらの代表者は、彼らが依存関係として、コントローラのコンストラクタに渡す必要があるから来てどこコントローラが知っているべきではありませんので:
public class EditCustomerController : Controller
{
private readonly CustomerService _customerService;
public EditCustomerController(CustomerServiceFactory customerServiceFactory
/*, ...any other dependencies required by the controller */
)
{
_customerService = customerServiceFactory(this.ModelState);
}
}
これは我々がこのように私たちのコンテナを構築する必要があります実現するために
public class CustomerService
{
private readonly IModelValidation _modelValidation;
public CustomerService(ModelStateDictionary msd,
ModelValidationFactory modelValidationFactory)
{
_modelValidation = modelValidationFactory(msd);
}
:
たCustomerServiceは次のようにコンストラクタを(必要に応じてServiceBaseクラスでこの一部を処理)が必要です
var builder = new ContainerBuilder();
builder.Register<ModelValidation>().As<IModelValidation>().FactoryScoped();
builder.Register<CustomerService>().FactoryScoped();
builder.RegisterGeneratedFactory<ModelValidationFactory>();
builder.RegisterGeneratedFactory<CustomerServiceFactory>();
builder.Register<EditCustomerController>().FactoryScoped();
したがって、コントローラが解決されると(例えばthe MvcIntegration moduleを使用する場合)、ファクトリデリゲートがコントローラとサービスに注入されます。
更新:私はhereを説明してきたようにあなたは、一般的な工場のデリゲートでCustomerServiceFactory
を置き換えることができ、さらに必要なコードを削減します。
を実装する必要があります。 –