Unity DI:从 per-request 到 global singleton 到 per-request 的解析
Unity DI: Resolving from per-request to global singleton to per-request
我有一个控制器调用全局单例,在 ASP.NET WebAPI 的上下文中调用每个请求实例。基本上
每个请求 => 单例 => 每个请求
下面的设置是否正确?我特别担心第二个按请求实例,因为它可能是基于用户的声明。
或者反模式和单例应该从控制器接收(每个请求)依赖项?
// UnityConfig.cs, the Resolver uses CreateChildContainer()
public static void RegisterTypes(IUnityContainer unity)
{
// global singleton
unity.RegisterType<MessageContext>(new ContainerControlledLifetimeManager());
// instance per request
unity.RegisterType<ClaimsContext>(new HierarchicalLifetimeManager());
}
// API controller
public class MyController : ApiController
{
private readonly MessageContext _message;
public FormController(MessageContext message)
{
_message = message;
}
public Task<IHttpActionResult> MyAction()
{
_message.FireAndForget();
return Ok();
}
}
// global singleton to keep connection pool
public class MessageContext
{
private readonly IUnityContainer _unity;
public MessageContext(IUnityContainer unity)
{
_unity = unity;
}
public Task FireAndForget()
{
// resolve per request
var claim = _unity.Resolve<ClaimsContext>().MyClaim);
// ...
}
}
正如评论中所指出的,上面的示例代码需要重构。为了解决这个问题,我将 MessageContext
分成了长期存在的部分和短期存在的部分。短命的部分接收短命的 ClaimsContext
,而长命的部分只持有长命的连接。
我有一个控制器调用全局单例,在 ASP.NET WebAPI 的上下文中调用每个请求实例。基本上
每个请求 => 单例 => 每个请求
下面的设置是否正确?我特别担心第二个按请求实例,因为它可能是基于用户的声明。
或者反模式和单例应该从控制器接收(每个请求)依赖项?
// UnityConfig.cs, the Resolver uses CreateChildContainer()
public static void RegisterTypes(IUnityContainer unity)
{
// global singleton
unity.RegisterType<MessageContext>(new ContainerControlledLifetimeManager());
// instance per request
unity.RegisterType<ClaimsContext>(new HierarchicalLifetimeManager());
}
// API controller
public class MyController : ApiController
{
private readonly MessageContext _message;
public FormController(MessageContext message)
{
_message = message;
}
public Task<IHttpActionResult> MyAction()
{
_message.FireAndForget();
return Ok();
}
}
// global singleton to keep connection pool
public class MessageContext
{
private readonly IUnityContainer _unity;
public MessageContext(IUnityContainer unity)
{
_unity = unity;
}
public Task FireAndForget()
{
// resolve per request
var claim = _unity.Resolve<ClaimsContext>().MyClaim);
// ...
}
}
正如评论中所指出的,上面的示例代码需要重构。为了解决这个问题,我将 MessageContext
分成了长期存在的部分和短期存在的部分。短命的部分接收短命的 ClaimsContext
,而长命的部分只持有长命的连接。