0

Проблема: У меня есть webapi serviss, где почти каждый пользователь имеет свой собственный экземпляр базы данных для подключения. Поэтому я должен установить разные connection string для каждого пользователя. Чтобы распознать пользователя, я передам конкретный токен в заголовок. Что касается на этом Токене, система должна построить и установить differenct строки соединения в конструктор слоя доступа к данным (Order в данном случае)Как установить аргумент для связывания 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

После реализации Дейва подхода, я понял, что я мог бы решить эту connection string инъекции путем подачи в HttpContext.CurrentNinject связывание, как это:

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