如何在请求标头上设置Ninject绑定器的参数

时间:2015-07-10 18:58:24

标签: asp.net-mvc ninject inversion-of-control ninject.web.mvc

问题: 我有webapi serviss,几乎每个用户都有自己的数据库实例进行连接。所以我必须为每个用户设置不同的connection string。要识别用户,我会将特定令牌传递到标头中。关于这个令牌,系统必须构建和设置差异连接字符串到数据访问层构造函数(在这种情况下为Order)

问题: 是否可以将参数传递给Ninject或任何类型的IoC绑定器关于请求标头?

    IOrders _orders;
    public HomeController(IOrders order)
    {
        _orders = order;
    }

这是一个Ninject绑定,但你可以猜到,HttpContext.Current为空。

    private static void RegisterServices(IKernel kernel)
    {
        var some_value = HttpContext.Current.Request.Headers.GetValues("Token");
        kernel.Bind<IOrders>()
            .To<Orders>()
            .WhenInjectedInto<HomeController>()
            .WithConstructorArgument("Token", some_value);
    }

使用Controller Factory可能有很多优雅的方法吗?

2 个答案:

答案 0 :(得分:1)

我会创建一个服务类来为您执行此查找。然后将此服务注入Orders实现。

public interface IRequestContext {
    string ConnectionString {get;}
}

public class HttpHeaderRequestContext : IRequestContext {
    public string ConnectionString {
        get {  
            var token = HttpContext.Current.Request.Headers.GetValues("Token");
            // .. lookup conn string based on token
        }
    }
}

public class Orders : IOrders {
    public Orders(IRequestContext ctx) {
        // create new connection w/ ctx.ConnectionString
    }
}

使用此方法,标头和连接字符串的查找将从实现中抽象出来。这使得在需要时使用不同的获取连接字符串的方法更容易测试和更换。

答案 1 :(得分:0)

在实施Dave方法后,我意识到我可以通过将connection string提供给HttpContext.Current绑定来解决此Ninject注入:

    private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind<IOrders>()
            .To<Orders>()
        .WhenInjectedInto<HomeController>()
        .WithConstructorArgument("smth", x => {
            var token = HttpContext.Current.Request.Headers.Get("Token");
            var _db = new SomeDataCxt();
            var connStr = _db.DbStringRepository.GetByToken(token);
            return connStr;
        });
    }