2009-11-30 2 views
5

私はすべての私のサービスが受け入れるModelStateDictionary上のラッパーを持っています。コントローラModelStateDictionaryをラッパーのコンストラクターに挿入し、それをサービスコンストラクターに注入するようにAutofacを構成することは可能ですか?AutofacでコントローラのModelStateをサービスコンストラクタに渡すにはどうすればいいですか?

//code 
public class ModelValidation : IModelValidation { 
public ModelValidation(ModelStateDictionary msd){...} 
.. 
.. 
} 

public class CustomerService{ 
public CustomerService(IModelValidation mv){...} 
.. 
} 

おかげ

+0

を実装する必要があります。 –

答えて

8

ご意見をもとに、私はここに私の答えを修正:)

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を置き換えることができ、さらに必要なコードを削減します。

+0

コンテナは新しいModelStateDictionaryを作成し、それをModelValidationコンストラクタに渡します。既存のModelStateDictionary(Controller.ModelStateプロパティからアクセス可能)をModelValidationコンストラクタに渡したいと思います。出来ますか? – Valentin

+0

あなたはあなたの質問でこれを詳しく説明できますか?静的なController.ModelStateですか?またはそれは今日どのように宣言されていますか? –

+0

Controller.ModelStateはModelStateDictionary型のプロパティです。コントローラはasp.net mvc runtime(コントローラファクトリ)によって作成され、そこでModelStateDictionaryが作成されます。コントローラをサブクラス化することでコントローラを作成でき、クラスのModelStateプロパティにアクセスできます。私が不明な場合は、私に知らせてください。私は質問をもっと詳しく書きます。 – Valentin

0

ValidationServiceなしで新しいコンストラクタを追加します。プロパティを使用してValidationServiceを割り当てます。

プロパティは、ちょうど工場代議員の束を宣言するからあなたを救う可能性が面白いアイデアで私の答えを更新インタフェースICostumerServiceに

public class ModelStateWrapper: IValidationDictionary { 
public ModelStateWrapper(ModelStateDictionary msd){} 
} 

public class CustomerService: ICostumerService{ 
public IValidationDictionary ValidationDictionary { get; set; } 
public CustomerService(ICustomerRepsitory customerRepository, IValidationDictionary validationDictionary){} 
public CustomerService(ICustomerRepsitory customerRepository){} 
} 

public Controller(ICustomerService customerService) 
{ 
    _customerService= menuService; 
    _customerService.ValidationDictionary = new ModelStateWrapper(this.ModelState); 
    _customerService= sportsService; 
} 
1
Builder.RegisterInstance(new ModelStateDictionary()).SingleInstance(); 
      builder.Register(c => new SW.PL.Util.ModelStateWrapper 
(c.Resolve<ModelStateDictionary>())).As<IValidationDictionary>().InstancePerHttpRequest(); 
+0

あなたはシングルインスタンスとして追加することができます – Farid

+0

この質問は、もはや実際の、あまりにも長いです。私は.NETをもはやプログラムしません:) – Valentin

関連する問題