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);
Другие вопросы по тегам