ASP.NET 5 从中间件注册 DI

ASP.NET 5 DI Registration From Middleware

我有一个中间件 class 可以让当前用户根据当前请求从数据库登录到应用程序:

public class CurrentUserMiddleware
{
    RequestDelegate m_next;
    UserManager<User> m_userManager;

    public CurrentUserMiddleware(RequestDelegate next, UserManager<User> userManager )
    {
        m_next = next;
        m_userManager = userManager;
    }

    public async Task Invoke(HttpContext context)
    {
        var userId = context.User.Identity.GetUserId();
        var user = await m_userManager.FindByIdAsync(userId);

        var currentUserContext = new CurrentUserContext { User = user };

        // Register CurrentUserContext with DI to this currentUserContext instance

        await m_next(context);
    }
}

解决后,我想注册一个 CurrentUserContext,可以通过 DI 在我的应用程序的其他区域解决。

例如:

public class HomeController : Controller
{
    private readonly CurrentUserContext m_currentUserContext;

    public HomeController(CurrentUserContext currentUserContext)
    {
        m_currentUserContext = currentUserContext;
    }

    public async Task<IActionResult> Index()
    {
        var userName = m_currentUserContext.User.Username;
        return View();
    }
}

如何正确注册此 CurrentUserContext?所有其他 DI 注册都在 Startup ConfigureServices 中完成,但是这不适用于这种情况,因为我需要在每个请求中解析 CurrentUserContext

不确定您使用的是什么 DI 容器,所以有点通用...

对于大多数 DI 容器,默认实例化是每次调用,因此无论它在对象实例化时在何处注册,您都可以访问当前上下文。大多数容器还提供了一个选项来指定 "factory" 方法,而不仅仅是类型名称 - 因此您可以从此类工厂调用 "Invoke" 方法。

请注意,大多数容器不支持 async 解析,因此您可以注册可以让您异步访问 "user context" 的对象:

 ICreateUserContext { Task<CurrentUserContext> GetContextAsync();}