インターフェイスにラップされたEFを使用してDbContext
、Webリクエストごとに依存性を注入し、リクエスト全体が同じコンテキストを処理するようにします。また、認証サービスをカスタマイズRoleProvider
するためにbyインターフェースを使用するカスタムもあります。DbContext
これまで、サービスロケーターパターンを使用してDbContext
、カスタムRoleProvider
の引数なしコンストラクターでインスタンスを解決してきました。は単調であるため、これによりいくつかの小さな問題が発生しました。そのため、無期限RoleProvider
に保持される可能性がDbContext
ありますが、他の要求では、の間にそれを破棄する必要がありApplication_EndRequest
ます。
ウィンザーとは異なるiocコンテナーを使用していますが、これに基づくソリューションがあります。DIを使用して、RoleProvider
httpリクエストごとにカスタムインスタンスを作成できます。
私の質問は、私がすべきですか?
オープンにDbContext
ぶら下がっているのRoleProvider
は無駄に思えます。一方、私はすべてのMVCAuthorizeAttribute
がヒットすることを知っているのでRoleProvider
(null以外のプロパティがある場合、ほとんどの場合そうです)、すでに待機Roles
していると便利だと思います。DbContext
別の方法は、 Webリクエストごとではないものに別DbContext
のものを注入することです。RoleProvider
このようにDbContext
して、Webリクエストに対してのみ存在するは、シングルトニーに影響を与えることなく、最後に破棄できRoleProvider
ます。
どちらのアプローチが優れていますか、そしてその理由は何ですか?
コメント後に更新
スティーブン、これは本質的に私がしたことです。唯一の違いは、に依存しないことSystem.Web.Mvc.DependencyResolver
です。代わりに、私は基本的に自分のプロジェクトにまったく同じものを持っていますが、名前が異なります。
public interface IInjectDependencies
{
object GetService(Type serviceType);
IEnumerable<object> GetServices(Type serviceType);
}
public class DependencyInjector
{
public static void SetInjector(IInjectDependencies injector)
{
// ...
}
public static IInjectDependencies Current
{
get
{
// ...
}
}
}
これらのクラスはプロジェクトのコアAPIの一部であり、MVCとは異なるプロジェクトにあります。System.Web.Mvc
このように、他のプロジェクト(およびドメインプロジェクト)は、そのプロジェクトに対してコンパイルするために依存関係をとる必要はありませんDependencyResolver
。
そのフレームワークを考えると、UnityをSimpleInjectorと交換することはこれまでのところ簡単です。多目的シングルトンRoleProviderセットアップは次のようになります。
public class InjectedRoleProvider : RoleProvider
{
private static IInjectDependencies Injector
{ get { return DependencyInjector.Current; } }
private static RoleProvider Provider
{ get { return Injector.GetService<RoleProvider>(); } }
private static T WithProvider<T>(Func<RoleProvider, T> f)
{
return f(Provider);
}
private static void WithProvider(Action<RoleProvider> f)
{
f(Provider);
}
public override string[] GetRolesForUser(string username)
{
return WithProvider(p => p.GetRolesForUser(username));
}
// rest of RoleProvider overrides invoke WithProvider(lambda)
}
Web.config:
<roleManager enabled="true" defaultProvider="InjectedRoleProvider">
<providers>
<clear />
<add name="InjectedRoleProvider" type="MyApp.InjectedRoleProvider" />
</providers>
</roleManager>
IoCコンテナ:
Container.RegisterPerWebRequest<RoleProvider, CustomRoleProvider>();
CUDに関しては、私の実装されているメソッドは1つだけCustomRoleProvider
です。
public override string[] GetRolesForUser(string userName)
これはMVC AuthorizeAttribute
(およびIPrincipal.IsInRole
)で使用される唯一のメソッドであり、他のすべてのメソッドから、私は単に
throw new NotSupportedException("Only GetRolesForUser is implemented.");
プロバイダーにはCUDopsの役割がないため、トランザクションについては心配していません。