WebI-интерфейс DI Framework, который понимает HttpContext.User
Я ищу структуру DI, которая может удовлетворить этот сценарий:
Каждый контроллер имеет такой конструктор
public ThisController( ThatRepository repo)
Каждый репозиторий имеет такой контроллер:
public ThatRepository (DataSource ds)
Существует один главный источник данных, но он никогда не передается в хранилище. Вместо этого нужно:
MasterDataSource.WithUser ( httpContext?.User?.Identity?.Name )
Существуют ли какие-либо структуры DI для WebAPI, которые бы поддерживали это из коробки?
2 ответа
Аннотация HttpContext
за интерфейсом, которым вы управляете, и ваш контейнер DI по своему усмотрению решает это при необходимости.
public interface ICurrentUser {
string Name{get;}
}
Конкретная реализация этого интерфейса может выглядеть так...
public class UserProvider : ICurrentUser {
HttoContextBase httpContext;
UserProvider(){
httpContext = HttpContext.Current;
}
public string Name {
get{ return httpContext?.User?.Identity?.Name ?? string.Empty; }
}
}
Вы регистрируете свой интерфейс / контракт в контейнере DI и разрешаете его при необходимости DataSource
,
public void SomeSetupMethod(ICurrentUser user) {
MasterDataSource.WithUser(user?.Name);
}
Я считаю, что вы можете использовать почти каждый DI-контейнер для этой цели, зарегистрировав текущий HttpContext
(или даже текущий пользователь Identity
) внутри контейнера, а затем вводить его для создания вашего DataSource
пример.
Вот простое решение с использованием HttpContext
в SimpleInjector (вы можете легко перенести код на любую инфраструктуру DI, которая вам нравится):
container.Register<HttpContextBase>(() =>
new HttpContextWrapper(HttpContext.Current),
Lifestyle.Scoped);
container.Register<DataSource>(() =>
{
var httpContext = container.GetInstance<HttpContextBase>();
return MasterDataSource.WithUser(httpContext?.User?.Identity?.Name);
},
Lifestyle.Scoped);