启用 Unity 以解决来自 OwinContext 的依赖项

Enable Unity to resolve dependencies from OwinContext

我有一个 ASP.NET Web 应用程序,它使用 Microsoft Identity 2.0 和 Unity.Mvc 进行依赖注入。

Microsoft Identity 2.0 在 OwinContext 中注册 UserManagerSignInManager 并依赖于 HttpContext.

我想在 ManageController

中注入这些
class ManageController
{
    public ManageController(IUserManager userManager, ISignInManager signInManager)
    {
    }
}

然而,这会引发异常,因为这些尚未在 UnityContainer.

中注册

我没有在 UnityContainer 中找到任何方法来向通过委托初始化的对象注册类型。类似的东西

container.RegisterInstance<IUserManager>(() => HttpContext.Current.GetOwinContext().GetUserManager<UserManager>());

我还尝试从 OwinContext 获取实例并在 UnityContainer

中注册它
var userManager = HttpContext.Current.GetOwinContext().GetUserManager<UserManager>();
container.RegisterInstance<IUserManager>(userManager);

然而 HttpContext.Currentnull

是否可以自定义 UnityContainer 类型映射行为?

为此,您可以编写自定义 UnityContainerExtension 并在该扩展中添加带有 UnityBuildStage.TypeMapping 的新策略,在该策略中,您可以覆盖 PreBuildUp 方法并从 OwinContext

我在自己的项目中是这样做的:

public class IdentityResolutionExtension : UnityContainerExtension
{
    public IdentityResolutionExtension(Func<IOwinContext> getOwinContext)
    {
        GetOwinContext = getOwinContext;
    }

    protected Func<IOwinContext> GetOwinContext { get; }

    protected override void Initialize()
    {
        Context.Strategies.Add(new IdentityTypeMappingStrategy(GetOwinContext), UnityBuildStage.TypeMapping);
    }

    class IdentityTypeMappingStrategy : BuilderStrategy
    {
        private readonly Func<IOwinContext> _getOwinContext;

        private static readonly MethodInfo IdentityTypeResolverMethodInfo =
            typeof (OwinContextExtensions).GetMethod("Get");

        public IdentityTypeMappingStrategy(Func<IOwinContext> getOwinContext)
        {
            _getOwinContext = getOwinContext;
        }

        public override void PreBuildUp(IBuilderContext context)
        {
            if (context.BuildComplete || context.Existing != null)
                return;

            var resolver = IdentityTypeResolverMethodInfo.MakeGenericMethod(context.BuildKey.Type);
            var results = resolver.Invoke(null, new object[]
            {
                _getOwinContext()
            });

            context.Existing = results;
            context.BuildComplete = results != null;
        }
    }
}

有关注册的更多信息UnityContainerExtension see this link