Resolve ()是否按会话返回对象?

在Microsoft Unity IoC中,如果我调用Resolve() ,我可以保证返回的对象是在当前会话期间创建的对象吗?

例如,三个用户登录,并且假设在容器中创建的SomeType对象对每个用户具有不同的值。 对Resolve的调用是否会返回为当前用户创建的对象? 或者它会做一些愚蠢的事情,比如返回创建的最后一个?

由于一些环境问题,我自己也遇到了麻烦,我需要尽快检查一下,所以如果有人能回答这个问题,那将非常有帮助!

编辑

原谅我,我是Unity的新手,但根据我在这里阅读的内容 ,似乎我应该能够在容器中注册具有唯一名称的对象,并通过该名称检索它们。 那么,我不能使用会话ID或会话中持续存在的其他值来检索我的对象吗?

哦哇,在MVC应用程序中使用Unity的终身管理。 我从哪里开始?

首先,会话单例实际上是不可能的,因为没有ASP.NET系统可以保证在同一会话中的请求之间使用相同的实例。 会话可以通过在请求之间对其进行序列化和反序列化来模仿会话中持久存在的同一对象。

瞬态实例 – 即没有生命周期管理规范的简单注册在99%的时间内都是足够的。 这意味着每次需要时都会创建一个已注册类型的实例。

在请求的整个生命周期中,您很少需要实例。 但是当你需要那些时,你真的需要那些。 与DB的连接是完美的候选者。 另一方面,请求单身人士更容易创建和管理。

最优雅的解决方案是使用Unity的子容器function。 可以在请求开始时创建子容器,在请求结束时处置(作为额外的奖励,它将处理所有ContainerControlledLifetimeManager实例)。

创建子容器时,所有注册仍可从父容器中获取,因此您需要使用子容器注册特定于请求的内容。

这是伪代码,使这个工作:

 private void Application_Start() { _parentContainer = new UnityContainer(); //creates a transient registration, available at any point in the app. _parentContainer.RegisterType(); 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(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 Factory以使用子容器来创建控制器。 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(controllerName)) controller = container.Resolve(controllerName); else controller = base.CreateController(requestContext, controllerName) ; return controller; } } 

默认行为是为每个解析调用返回一个新实例,这不是您想要的。

可以在会话中创建和解析相同的实例,但据我所知,没有内置支持。 您必须编写自己的生命周期管理器,然后在注册类型时使用它。

每个线程实例都有一个生命周期管理器,但这对于会话没有用,因为线程将被重用,并且解析还需要跨多个请求才能真正实现会话范围。

完全有可能有人为此写了终身经理。