あなたのコメントに基づいて、私はここに私の答えを修正します:)
ModelStateDictionary
コンテナによって解決されるべきサービスではなく、インスタンス化時に提供されるべきデータであることは明らかです。ModelState は各 Controller インスタンスによって所有されているため、「解決時」にコンテナーで使用できないという事実からわかります。
さらに、各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);
}
}
CustomerService には、これに似たコンストラクターが必要です (オプションで、この一部を ServiceBase クラスで処理します)。
public class CustomerService
{
private readonly IModelValidation _modelValidation;
public CustomerService(ModelStateDictionary msd,
ModelValidationFactory modelValidationFactory)
{
_modelValidation = modelValidationFactory(msd);
}
これを実現するには、次のようにコンテナを構築する必要があります。
var builder = new ContainerBuilder();
builder.Register<ModelValidation>().As<IModelValidation>().FactoryScoped();
builder.Register<CustomerService>().FactoryScoped();
builder.RegisterGeneratedFactory<ModelValidationFactory>();
builder.RegisterGeneratedFactory<CustomerServiceFactory>();
builder.Register<EditCustomerController>().FactoryScoped();
そのため、コントローラーが解決されると ( MvcIntegration モジュールを使用する場合など)、ファクトリー デリゲートがコントローラーとサービスに注入されます。
更新: 必要なコードをさらに削減するには、ここでCustomerServiceFactory
説明したような一般的なファクトリ デリゲートに置き換えることができます。