私が書いているクラスライブラリで興味深いデザイン問題が発生しました。私は、クライアントがこのように使用することができるようにしたいAuthorizeAttributeのカスタム実装があります。クラスライブラリのAuthorizeAttributeへの依存関係の注入
[Protected("permission_name")]
上記のコードでは、PermissionAttributeは(デフォルトコンテキストがのHttpContextを使用して作成)AuthorizeAttributeから継承し、ローカルのデフォルトを使用しています。
この属性では、SecurityServiceを使用してユーザー、ロール、およびアクセス許可をチェックします(SecurityService自体は、クライアント提供の永続性サービスを使用してアプリケーションの構成ルートに接続できます)。
したがって、私の属性には、機能するSecurityServiceへの参照が必要です。属性コンストラクタはコンパイル時定数しか持てないので、コンストラクタインジェクションは使用できません。
私はDIフレームワークを使用するように私のクライアントを強制的にしたくない - は、彼らがそう選択した場合、IoCのライブラリを使用せずにアップし、その組成のルートで必要な依存関係をとワイヤーを発見するために、彼らはできるはずです。ここで
は私のオプションは次のとおりです。
- は、ライブラリの使用にシングルトンSecurityServiceを持っています。
- 働くだろう使用プロパティ注射が、
- それが依存関係になるだろう、それは私がAUTHORIZE属性にMVCアプリのプロパティインジェクションを行うことができますどこ私にはわからないではないと
- れ、オプションのように見えます。
上記2に対する可能な解決策は次のように、アプリケーションの起動時に属性に静的プロパティとしてSecurityServiceのインスタンスを設定し、複数回に設定されることを防止するために、ガード句を使用しないことですこの:それは別の実装によって置き換え/拡張することができるように
class ProtectedAttribute : ...
{
private static ISecurityService _SecurityService ;
public static ISecurityService SecurityService
{
get
{
return _SecurityService ;
}
set
{
if (_SecurityService != null)
throw new InvalidOperationException("You can only set the SecurityService once per lifetime of this app.") ;
_SecurityService = value ;
}
}
}
SecurityServiceが抽象サービス・ファサードである可能性があります。
この問題を解決するには、より良い方法がありますか?
UPDATE:
public class ProtectedAttribute : ...
{
private string _Permission ;
public string Permission { get { return _Permission ; } /*...*/ }
public ProtectedAttribute(string permission) { /*...*/ }
}
セットアップの許可フィルタと依存関係を設定します。
は、アクセス権の名前を返す属性にパブリックプロパティを追加します。いくつかのコードを追加すると、私はそれをするつもりですか表示しますNinject(Ninjectを使用している場合)経由:
using Ninject.Web.Mvc.FilterBindingSyntax;
public class MyModule : Ninject.Modules.NinjectModule
{
public override void Load()
{
// mySecurityService instance below can have a singleton lifetime - perfect!
this.BindFilter<MyAuthorizationFilter>(FilterScope.Action, 0)
.WhenActionMethodHas<ProtectedAttribute>()
.WithConstructorArgument("securityService", mySecurityService)
.WithConstructorArgumentFromActionAttribute<ProtectedAttribute>("permission", p => p.PermissionName) ;
}
}
あー、それはだ...美しい嗅ぐ
このASP.NET MVC 3ですか? –
@ダリン:はい、最低限のMVC 3が必要です。タグを更新しました。 –
関連:http://stackoverflow.com/questions/7192543/injecting-dependencies-into-asp-net-mvc-3-action-filters-whats-wrong-with-this/7194467#7194467 –