如何根据请求 header 将参数设置为 Ninject 活页夹

How to set argument to Ninject binder regarding on request header

问题: 我有 webapi 服务,几乎每个用户都有自己的数据库实例要连接。所以我必须为每个用户设置不同的connection string。为了识别用户,我会将特定的令牌传递给 header。关于此令牌,系统必须构建不同的连接字符串并将其设置到数据访问层构造函数中(在本例中为顺序)

问题: 是否可以将参数传递给 Ninject 或关于请求 header 的任何类型的 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 来做到这一点?

我会创建一个服务 class 来为您执行此查找。然后将此服务注入订单实施。

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
    }
}

使用此方法,headers 和连接字符串的查找从实现中抽象出来。这使得测试更容易,并且在需要时更容易换成另一种获取连接字符串的方法。

实施 Dave 方法后,我意识到我可以通过将 HttpContext.Current 馈送到 Ninject 绑定来解决此 connection string 注入,如下所示:

    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;
        });
    }