在 Microsoft Unity IoC 中,如果我调用 Resolve<SomeType>()
, 我可以保证返回的对象是在当前 session 期间创建的对象吗?
例如,三个用户登录,假设SomeType
的对象在容器中创建的每个用户都有不同的值。会调用 Resolve
返回为当前用户创建的对象?或者它会做一些愚蠢的事情,比如返回最后创建的一个吗?
由于一些环境问题,我自己测试时遇到了麻烦,我需要尽快检查一些东西,所以如果有人能回答这个问题,那将非常有帮助!
编辑
请原谅我是 Unity 的新手,但基于 what I read here ,似乎我应该能够使用唯一名称在容器中注册对象并通过该名称检索它们。那么,难道我不能使用 session ID 或 session 中持续存在的其他一些值来检索我的对象吗?
最佳答案
哇哦,在我的 MVC 应用程序中使用 Unity 进行生命周期管理。我从哪里开始?
首先, session 单例实际上是不可能的,因为没有 ASP.NET 系统可以保证在同一 session 中的请求之间使用同一实例。 session 可以通过在请求之间对其进行序列化和反序列化来模拟在 session 中持久保存的同一对象。
transient 实例——即没有生命周期管理规范的简单注册在 99% 的时间里就足够了。这意味着每次需要时都会创建注册类型的实例。
您很少需要实例在请求的整个生命周期内都存在。但是,当您需要这些时,您确实需要它们。与数据库的连接是一个完美的选择。另一方面,请求单例更容易创建和管理。
最优雅的解决方案是使用 Unity 的子容器功能。子容器可以在请求开始时创建,在请求结束时释放(作为额外的好处,它将释放所有 ContainerControlledLifetimeManager
实例)。
当创建子容器时,所有注册仍然可以从父容器获得,因此您需要向子容器注册请求特定的内容。
以下是实现此功能的伪代码:
private void Application_Start() {
_parentContainer = new UnityContainer();
//creates a transient registration, available at any point in the app.
_parentContainer.RegisterType<IParentIntf, ParentIntfImpl>();
ControllerBuilder.Current.SetControllerFactory(new ServiceLocatorControllerFactory());
}
private void Application_BeginRequest() {
var childContainer = _parentContainer.CreateChildContainer();
//registers a request "singleton"
//This registration is a type registration, an instance of RequestInterfaceImpl
//will be created when needed and then kept in the container for later use.
childContainer.RegisterType<IRequestInterface,RequestInterfaceImpl>(new ContainerControlledLifetimeManager());
//save the child container in the context, so we can use it later
HttpContext.Items["childContainer"] = childContainer;
}
private void Application_EndRequest() {
//dispose the child container
((IUnityContainer)HttpContext.Items["childContainer"]).Dispose();
}
需要做的另一件事是覆盖 Controller 工厂以使用子容器创建 Controller 。 Controller 是应用程序的第一个入口点,它们可以简单地在构造函数中依赖其他组件。
public class UnityControllerFactory : DefaultControllerFactory {
#region IControllerFactory Members
public override IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName) {
IController controller;
controllerName = controllerName.ToLower();
var container = ((IUnityContainer)HttpContext.Items["childContainer"])
if(container.IsRegistered<IController>(controllerName))
controller = container.Resolve<IController>(controllerName);
else
controller = base.CreateController(requestContext, controllerName) ;
return controller;
}
}
关于c# - Resolve<T>() 是否按 session 返回对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4651844/