.NET MVC:为(有效)每个请求的生命周期配置Unity

时间:2017-09-11 17:00:57

标签: c# asp.net-mvc dependency-injection unity-container

我正在构建一个基于MVC的UI,它与WebAPI 2 REST API进行通信。 UI具有多个层,底层是REST API的代理。当请求进入任何MVC控制器时,我们在入口点捕获一些元信息,我们希望在我们对REST API的请求中传入HTTP头。

我们正在使用Unity进行DI,按惯例注册(以及明确注册的一些项目)设置如下:

    private static void RegisterByConvention(IUnityContainer container)
    {
        var loadedAssemblies = AllClasses.FromLoadedAssemblies().Where(a => a.GetInterfaces()
            .Any(
                i => i.Namespace != null
                     && i.Namespace.StartsWith(ApplicationNamespace))).ToArray();

        container.RegisterTypes(
            loadedAssemblies,
            WithMappings.FromMatchingInterface,
            WithName.Default,
            WithLifetime.PerThread,
            null,
            true);
    }

    private static void RegisterExplicitly(IUnityContainer container)
    {
        container.RegisterType<IWebApiProxy, WebApiProxy>(
            new PerThreadLifetimeManager(),
            new InjectionConstructor(string.Empty, string.Empty, Guid.Empty));
    }

请注意,我在上面的代码中使用了 PerThread 生命周期管理器,但我已经尝试过几乎所有终身管理器(下面有更多内容)。我最初选择PerThread的原因是因为dev guide

  

对于这个生命周期管理器,Unity在每个线程的基础上返回   每次调用时注册类型或对象的相同实例   Resolve或ResolveAll方法或依赖机制注入时   实例到其他类。这个终身经理有效   基于每个线程实现对象的单例行为。   PerThreadLifetimeManager从容器中返回不同的对象   对于每个线程。

请注意,我们所有的MVC控制器都继承自具有此方法的基本控制器:

    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        // gather meta data... 
        this._container.RegisterInstance(
            new WebApiProxy(metaData1, metaData2, metaData3));
    }

这里的想法是,对于进入MVC控制器的每个调用,我们将注册一个WebApiProxy的新实例,该实例将在使用适当的元数据构建的调用链中进一步使用。这里的目标是抽象处理这个元数据,这样开发人员就不必在我们需要调用WebApiProxy的任何地方将它传递到堆栈。

然而......有问题。我发现,通过多次调用将不同的元数据传递给被覆盖的&#34; OnActionExecuting&#34;函数,有时调用将使用旧元数据的WebApiProxy实例化。

我有一种感觉问题是我的配置和(希望)使用DI容器没有更大的问题。任何可以指导我如何保证始终拥有被覆盖的&#34; OnActionExecuting&#34;中使用的相同数据的人。函数在同一个调用链中的WebApiProxy实例化中可用将非常感激。

编辑: 有一点需要注意,我使用async并等待从入口点到WebApiProxy,但我不会认为应该对这里的行为产生任何影响。

编辑2: 好吧,我现在放弃了这项技术,并使用HttpContext来存储和引用我需要的元数据。我稍后会回过头来找出一种方法来实现这个。

0 个答案:

没有答案