4

ASP.NET MVC 3 で複数の依存関係リゾルバーを使用することは可能ですか (ModelBinders と Provider の場合と同様)?

4

2 に答える 2

7

複数の「コンテナー」または「リゾルバー」を使用すると便利なシナリオが 1 つあります。それがマルチテナンシーです。マルチテナンシーを使用すると、複数の顧客 (独自のユーザー セットを持つ組織) を同じ Web アプリケーションで実行し、ログイン、要求情報、またはドメイン情報に基づいて動的に切り替えることができます。

それでも、DependencyResolver.Current- Darinが指摘したように - 静的であるため、できることは何もありません(またはこれについて行う必要があります)。ただし、単一のIDependencyResolver抽象化の背後に複数のコンテナーを隠し、いくつかの基準に基づいて実装を返すことができます。次のようになります。

public class MultiTenantDependencyResolver 
    : IDependencyResolver
{
    Func<int> tenantIdSelector,;
    IDictionary<int, IDependencyResolver> tenantResolvers;

    public MultiTenantDependencyResolver(
        Func<int> tenantIdSelector,
        IDictionary<int, IDependencyResolver> tenantResolvers)
    {
        this.tenantIdSelector = tenantIdSelector;
        this.tenantResolvers= tenantResolvers;
    }

    private IDependencyResolver CurrentResolver
    { 
        get { return this.tenantResolvers[tenantIdSelector()]; }
    }

    public object GetService(Type serviceType)
    {
        return this.CurrentResolver.GetService(serviceType);
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        return this.CurrentResolver.GetAllInstances(serviceType);
    }
}

次のコード スニペットは、 this の使用法を示していますMultiTenantDependencyResolver

var tenantResolvers = new Dictionary<int, IDependencyResolver>
{
    { Tenants.AbcId, BuildResolver(RegisterForTenantAbc) },
    { Tenants.KlmId, BuildResolver(RegisterForTenantKlm) },
    { Tenants.XyzId, BuildResolver(RegisterForTenantXyz) },
};

var multiTenantResolver = new MultiTenantResolver(
    () => GetTenantIdFromUrl(), tenantResolvers);

DependencyResolver.SetResolver(multiTenantResolver);


private static int GetTenantIdFromUrl()
{
    // TODO: return tenant id
}

private static IDependencyResolver BuildResolver(
    Action<IKernel> tenantSpecificRegistrations)
{
    var kernel = new Kernel();

    // TODO: Tenant agnostic registrations. For instance
    kernel.Bind<ITimeProvider>().To<SystemTimeProvider>();

    tenantSpecificRegistrations(kernel);

    return new NinjectDependencyResolver(kernel);
}

private static void RegisterForTenantAbc(IKernel kernel)
{
    // TODO: regisrations for ABC tenant. For instance
    kernel.Bind<ILogger>().To<AbcTenantLogger>();
}
于 2013-04-05T21:57:48.513 に答える