3

キャッスルウィンザーは初めてです。依存関係の解決に関しては、.NETMVCアプリケーションで完全に正常に機能しています。現在、コンストラクターインジェクション(Eg1)またはプロパティインジェクション(2)を使用して、コントローラーの依存関係を解決しています。問題は、プロパティインジェクションを使用して別のクラス(コントローラークラスではない)の依存関係を解決しようとすると、これが自動的に解決されないことです(例3)

例1-解決OK!

public class HomeController : Controller
{
    private IUserRepo _userRepo;

    public HomeController(IUserRepo userRepo)
    {
       _userRepo = userRepo;
    }

    public ActionResult Show()
    {
        return View(userRepo.GetAllUsers());
    }

}

例2-解決OK!

public class HomeController : Controller
{
    public IUserRepo _userRepo {get;set;}

    public HomeController()
    {
    }

    public ActionResult Show()
    {
       return View(_userRepo.GetAllUsers());
    }
}

例3-未解決!

public class ValidationRepository
{
   public IUserRepo _userRepo {get;set;}

   public bool ValidateUser()
   {
        //Here _userRepo is never resolved.
        // NB: I want property injection instead of constructor injection, is there any way?
   }
}

ありがとう

4

2 に答える 2

0

依存関係が解決されない理由を明確に述べるのに十分なコードを示していません。クラスがどのようにインスタンス化されるかを示していません。これは、依存関係がどのように/解決されるかを理解する上で非常に重要です。

とはいえ、ここで知識に基づいた推測を行うことができます。

コントローラーは、コンテナー (ウィンザー) を介して各コントローラーを解決するコントローラー ファクトリを使用しています。ValidationRepository は、コンテナーによって管理されていない他の方法で作成されています (例: new ValidationRepository())。依存関係の解決が機能するためには、ValidationRepository がコントローラーと同じ依存関係チェーンに属している必要があります。つまり、コントローラーの 1 つの依存関係 (または依存関係の依存関係、したがって、依存チェーン)。

実際に ValidationRepository を手動で ( を使用してnew) インスタンス化している場合、コントローラーはクラスを認識していないため、その依存関係を解決できません。ValidationRepository をコントローラーの 1 つに対するコンストラクターの依存関係にしてみて、それが機能するかどうかを確認してください。

于 2012-05-27T13:30:25.057 に答える
0

IUserRepo と ValidationRepository のインスタンス化が、Windsor コンテナーに登録されていることを確認してから、コンテナー内の他の項目 (コントローラーなど) がそれらに依存し、それらが相互に依存するようにする必要があります。たとえば、次のようなものです。

container.Register(
            Component.For<IUserRepo>()
            .LifeStyle.Transient.
            .ImplementedBy<YourRealUserRepo>());

container.Register(
            Component.For<ValidationRepository>()
                .LifestyleTransient());

あなたが書いたものを考えると、コントローラーが IUserRepo のインスタンス化を喜んで拾っているので、最初のステップをすでに処理しているように見えます。

ValidationRepository もそこにあると、プロパティ注入またはコンストラクター注入のいずれかを使用でき、すべて機能します。

ただし、これはすべて、Castle Windsor コンテナーから ValidationRepository のインスタンスを取得した場合にのみ機能することに注意してください。「new ValidationRepository()」を実行すると、コンテナーの外部でインスタンス化され、Castle Windsor は依存関係を注入することを認識しません。理想的には、ValidationRepository は、依存オブジェクトのプロパティまたはコンストラクター パラメーターとして、コンテナー内の別のオブジェクトの依存関係になります。その後、Castle Windsor は必要に応じてインスタンスを作成します。

これを行うと、依存関係が完全に解決されたインスタンスを取得できます。

var validationRepository = Container.Resolve<ValidationRepository>();

「Container」は Castle Windsor Container への参照であり、最初に Container をセットアップするときに、ある種の IoC Utility クラスの静的プロパティに割り当てた可能性があります。

ただし、これはService Locator Anti-patternの一例であり、避ける必要があります。代わりに、MVC パイプラインの一部としてコントローラーのインスタンス化をコントローラー ファクトリに任せてから、プロパティまたはコンストラクター パラメーターのいずれかとして、その他の必要なすべての依存関係をそこから連鎖させることをお勧めします。たとえば、コントローラーには ValidationRepository 依存関係があり、ValidationRepository には IUserRepo 依存関係があります。

于 2012-05-27T13:54:42.787 に答える