5

I'm trying to implement my custom authorize attribute like:

 public class MyCustomAuth : AuthorizeAttribute
{
    private readonly IUserService _userService;

    public MyCustomAuth(IUserService userService)
    {
        _userService= userService;
    }
... continued
 }

I am using Castle Windsor for automatically resolve the dependency.

When I try to use it as an attribute of an action method obviously I am asked to pass the parameter or I need to have a parameter-less constructor that should resolve in some way it's dependency.

I tried to inject the dependency with a property but Windsor is not injecting it.

The only option I see now would be to instantiate manually the concrete object dependency loosing the benefit of Windsor.

How would you solve this problem?

4

3 に答える 3

1

城のコードや構成例を提供していません。したがって、あなたはキャッスルを初めて使用し、登録プロセスに慣れていないと想定しています。

まず第一に、操作したいオブジェクトは、登録されたタイプを介してウィンザー城から取得する必要があります。そうは言っても、城のウィンザーを属性で使用しようとすると、間違った道を進んでいます-属性はコードで参照されず、代わりに反映されるためです。したがって、IoC (この場合はウィンザー城) がオブジェクトを作成する場所がありません。

私がこれを言うのは、あなたが達成しようとしていることは、すでに別の手段で行われているからです。まず、依存性注入をコントローラーに配置します。

public class PostController
{
  private IUserService _userService;
  public PostController (IUserService userService)
  {
    _userService = userService;
  }

  // other logic

}

Castle が機能するには、すべてのタイプを登録する必要があります。そのため、Castle Windsor 内で IUserService と、そのインターフェイスを実装するサービスを登録する必要があります。これは、global.asax で container.AddComponentWithLifeStyle; を使用して手動で行うことができます。または、より好ましい方法は、構成ファイルを使用することです。

構成ファイルを使用すると、IUserService は次のようになります。

<?xml version="1.0" encoding="utf-8" ?>
<castle>
    <components>
        <!--lifestyle="singleton|thread|transient|pooled|webrequest|custom"-->

        <component
            id="UserService"
            service="MyMvcProject.IUserService, MyMvcProject"
            type="MyMvcProject.UserService, MyMvcProject"
            lifestyle="transient">
        </component>
    </components>
</castle>

MyMvcProject はプロジェクトの名前であり、インターフェイスと型の正確な名前空間と完全修飾名を使用してください。実際の名前空間のコード サンプルを提供してください。

それが機能する前に、app.config または web.config を変更して、Castle Windsor の searchGroup を登録する必要があります。

<configSections>

    <section name="castle" 
        type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor"/>

</configSections>

<castle configSource="castle.config"/>

すべての登録とセットアップが完了したので、MVC アプリケーションに「Castle Windsor を使用してコントローラーの各インスタンスを作成する」ように指示します。これを行うと、Inversion-of-Control (別名 IoC) コンテナーである Castle Windsor がコントローラーの依存関係を検査し、それが IUserService に依存しており、 UserService のインスタンスを実装していることを確認します。Castle は、登録された型の構成を調べて、IUserService のサービスが登録されていることを確認します。そして、IUserService を実装する UserService の具象クラスを実装する必要があることが構成ファイルに表示されます。そのため、IUserService への依存関係が要求されると、IoC コンテナーは UserService を返します。

ただし、その前に、MVC アプリケーションに、構成済みの IC コンテナーを使用するように指示する必要があります。これを行うには、新しい ControllerFactory を登録します。それを行うには、この質問で私の回答を参照してください。

Castle Windsor が「Content」および「Scripts」フォルダーをコントローラーとして解決しようとするのはなぜですか?

そして、そのコードを登録する方法の global.asax 部分に注目してください。それはかなりうまくいきます!

ここまでの説明がすべて終わったら、ユーザーを承認する必要があります。フォーム認証を実装する通常の [Authorize] を使用し、_userService を使用して、サインインしているユーザーのユーザー詳細を取得します。

于 2009-11-06T18:59:57.827 に答える