Это ошибка.
После некоторой чрезмерной отладки исходного кода spring.net мы обнаружили:
- Поддержка объектов сессий предоставляется
spring.web
dll
- DLL
spring.web.mvc
не зависит от spring.web
- Это означает, что невозможно создать экземпляр
MvcApplicationContext
, который может разрешать объекты сессий
Следующее решение демонстрирует пользовательский MvcApplicationContext
, который полностью включает объекты области сеанса в MVC3 с использованием spring.net.
Причина, по которой стандартный контекст приложения не может разрешить веб-области, заключается в том, что он использует класс RootObjectDefinition
, поскольку он не знает об атрибуте scope
(в конфигурации XML). Вместо этого WebApplicationContext
создает экземпляры RootWebObjectDefinition
типов, которые знают область действия.
WebObjectsFactory
переопределяет метод CreateRootObjectDefinition
, который возвращает экземпляры RootWebObjectDefinition
. Это тот, который мы хотим вернуть из контекста нашего приложения. Это делается путем переопределения метода CreateObjectsFactory
.
Следующая вещь, которую мы должны переопределить, это метод CreateXmlObjectDefinitionReader
. Когда весна читает метаданные из конфигурации, она не будет анализировать дополнительные атрибуты, такие как scope
, если мы не выберем определенного читателя. Поэтому мы будем использовать WebObjectDefinitionReader
в контексте нашего приложения.
Для конфигурации объектов вашей области сеанса вы можете либо пропустить атрибут singleton
, либо явно установить для него true
. В противном случае со значением false
область сеанса будет точно отключена.
* * Пример тысяча сорок-одиной: * +1042 *
<objects xmlns="http://www.springframework.net">
<object id="shoppingCart" type="ShoppingCart, ..." singleton="true" scope="session" />
</objects>
Пошаговое решение:
- Создать
MvcWebApplicationContext
наследуя от MvcApplicationContext
. Вам нужно будет переопределить два метода, упомянутых выше, и создать конструкторы по умолчанию.
- Создайте
MvcWebContextHandler
наследуя от MvcContextHandler
. Это приведет к тому, что будет использоваться наш пользовательский контекст приложения.
- Используйте пользовательский контекстный обработчик в вашем
web.config
.
- Для поддержки IIS6 или встроенного веб-сервера Visual Studio: добавьте
WebSupportModule
в system.web
раздел.
- Для поддержки IIS7: добавьте
WebSupportModule
в system.webserver
раздел.
web.config:
<configSections>
<sectionGroup name="spring">
<section name="context" type="YourNamspace.MvcWebContextHandler, YourAssembly"/>
....
</sectionGroup>
....
</configSections>
<!-- IIS6 -->
<system.web>
<httpModules>
<add name="Spring" type="Spring.Context.Support.WebSupportModule, Spring.Web"/>
</httpModules>
</system.web>
<!-- IIS7 -->
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules runAllManagedModulesForAllRequests="true" >
<add name="Spring" type="Spring.Context.Support.WebSupportModule, Spring.Web"/>
</modules>
</system.webServer>
Класс пользовательского контекста приложения:
public class MvcWebApplicationContext: MvcApplicationContext {
public MvcWebApplicationContext(string name, bool caseSensitive, params string[] configurationLocations)
: this(new MvcApplicationContextArgs(name, null, configurationLocations, null, caseSensitive))
{ }
public MvcWebApplicationContext(string name, bool caseSensitive, IApplicationContext parentContext, params string[] configurationLocations)
: this(new MvcApplicationContextArgs(name, parentContext, configurationLocations, null, caseSensitive))
{ }
public MvcWebApplicationContext(MvcApplicationContextArgs args)
: base(args)
{ }
public MvcWebApplicationContext(string name, bool caseSensitive, string[] configurationLocations, IResource[] configurationResources)
: this(new MvcApplicationContextArgs(name, null, configurationLocations, configurationResources, caseSensitive))
{ }
public MvcWebApplicationContext(params string[] configurationLocations)
: this(new MvcApplicationContextArgs(string.Empty, null, configurationLocations, null, false))
{ }
protected override XmlObjectDefinitionReader CreateXmlObjectDefinitionReader(DefaultListableObjectFactory objectFactory)
{
return new WebObjectDefinitionReader(GetContextPathWithTrailingSlash(), objectFactory, new XmlUrlResolver());
}
protected override DefaultListableObjectFactory CreateObjectFactory()
{
return new WebObjectFactory(GetContextPathWithTrailingSlash(), IsCaseSensitive);
}
private string GetContextPathWithTrailingSlash()
{
string contextPath = this.Name;
if (contextPath == DefaultRootContextName)
{
contextPath = "/";
}
else
{
contextPath = contextPath + "/";
}
return contextPath;
}
}
Класс обработчика пользовательских контекстов:
public class MvcWebContextHandler : MvcContextHandler {
protected override Type DefaultApplicationContextType
{
get { return typeof(MvcWebApplicationContext); }
}
}
Мы добавили эту ошибку в систему отслеживания проблем Spring.NET:
https://jira.springsource.org/browse/SPRNET-1450