我正在构建一个基于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来存储和引用我需要的元数据。我稍后会回过头来找出一种方法来实现这个。