0

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

问: 是否可以传递参数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

回答

1

我会创建一个服务类,为你做这个查找。然后将此服务注入订单实施。

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

使用此方法时,将头部和连接字符串的查找从实现中抽象出来。这使得测试变得更容易,并且如果需要的话,可以用另一种获得连接字符串的方法来更换。

0

实施戴夫方法后,我发现我可以通过喂养HttpContext.Current解决这个connection string注入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; 
     }); 
    }