2010-01-11 3 views
0

Я пытаюсь создать приложение ASP.NET MVC, используя Spring.NET для инъекций зависимостей. Приложение имеет три уровня: контроллер, служба и данные.Spring.NET Зависимости, которые не вводятся

Я определил объекты в файле «~ \ Resources \ objects.xml».

Мой первый объект, UserAccountController, требует применения двух классов Service-level: UserAccountService и DepartmentService. Таким образом, определение в objects.xml выглядит следующим образом:

<object id="UserAccountController" type="App.Controllers.UserAccountController, App"> 
    <constructor-arg index="0" ref="DepartmentService" /> 
    <constructor-arg index="1" ref="UserAccountService" /> 
</object> 

<object id="UserAccountService" type="App.Service.UserAccountService, App"> 
    <property name="UserAccountDao" ref="UserAccountDao" /> 
</object> 

<object id="UserAccountDao" type="App.Data.UserAccountDao, App" /> 

<object id="DepartmentService" type="App.Service.DepartmentService, App"> 
    <property name="DepartmentDao" ref="DepartmentDao" /> 
</object> 

<object id="DepartmentDao" type="App.Data.DepartmentDao" /> 

WebConfig содержит следующее:

<sectionGroup name="spring"> 
     <section name="context" type="Spring.Context.Support.WebContextHandler, Spring.Web"/> 
    </sectionGroup> 
</configSections> 
<spring> 
    <context> 
     <resource uri="~/Resources/objects.xml" /> 
    </context> 
</spring> 

Я предпочел бы использовать инъекции собственности, а не конструктор, но в данный момент ни один метод работает.

ответ

3

Ну, это, оказалось, что ASP.NET MVC и Spring.NET просто не ладите ...

Однако пакет MvcContrib (фактически, пакет Extras), похоже, решил проблему. В пакете была реализована заводская реализация Spring Controller, и все было счастливо.

(Вид напоминает мне о попытке сделать Struts 1.x и Spring работать на стороне Java ...)

1

в вашем bootstrapclass вы должны загрузить весной контейнер

ContextRegistry.getContext(); 

по пути вам необходимо указать имя сборки для DepartmentDao

<object id="DepartmentDao" type="App.Data.DepartmentDao, App" /> 
+0

Я на самом деле есть класс SpringApplicationController и класс Spring ControllerFactory, и ссылки на них в Global.asax .cs: ​​ ControllerBuilder.Current.SetControllerFactory (typeof (App.Util.SpringControllerFactory)); Должен ли я получить контекст, если я использую этот метод? – Jason

+0

честно, я не знаю. Но, очевидно, нет. Лучшей практикой для инверсии управления является загрузка контейнера в начале приложения и отсутствие других ссылок на контейнер. Если конфигурация выполнена хорошо, вызовите ContextRegistry.getContext(); должен обрабатывать все – Fabiano

+0

Хорошо, я бросил причудливые реализации ControllerFactory и ApplicationContext в пользу простого вызова ContextRegistry.getContext() и переключился на обычный ContextHandler в web.config. Все еще не удача в инъекции. – Jason

0

Дополнительная информация: У меня также есть классы для SpringApplicationController и SpringControllerFactory:

SpringApplicationController.cs:

public static class SpringApplicationContext 
{ 
    private static IApplicationContext Context { get; set; } 

    /// <summary> 
    /// Returns a boolean value if the current application context contains an named object. 
    /// </summary> 
    /// <param name="objectName">Accepts the name of the object to check.</param> 
    public static bool Contains(string objectName) 
    { 
     SpringApplicationContext.EnsureContext(); 
     return SpringApplicationContext.Context.ContainsObject(objectName); 
    } 

    /// <summary> 
    /// Return a instance of an object in the context by the specified name. 
    /// </summary> 
    /// <param name="objectName">Accepts a string object name.</param> 
    public static object Resolve(string objectName) 
    { 
     SpringApplicationContext.EnsureContext(); 
     return SpringApplicationContext.Context.GetObject(objectName); 
    } 

    /// <summary> 
    /// Return a instance of an object in the context by the specified name and type. 
    /// </summary> 
    /// <typeparam name="T">Accepts the type of the object to resolve.</typeparam> 
    /// <param name="objectName">Accepts a string object name.</param> 
    public static T Resolve<T>(string objectName) 
    { 
     return (T)SpringApplicationContext.Resolve(objectName); 
    } 

    private static void EnsureContext() 
    { 
     if (SpringApplicationContext.Context == null) 
     { 
      SpringApplicationContext.Context = ContextRegistry.GetContext(); 
     } 
    } 
} 

SpringControllerFactory.cs:

public class SpringControllerFactory : DefaultControllerFactory 
{ 
    public IController CreateController(RequestContext context, Type controllerType) 
    { 
     IResource input = new FileSystemResource(context.HttpContext.Request.MapPath("Resource\\objects.xml")); 
     IObjectFactory factory = new XmlObjectFactory(input); 

     return (IController) factory.GetObject(controllerType.Name); 
    } 

    public IController CreateController(RequestContext context, string controllerName) 
    { 
     IController controller = null; 
     string controllerClassName = string.Format("{0}Controller", controllerName); 

     if (SpringApplicationContext.Contains(controllerClassName)) 
     { 
      controller = SpringApplicationContext.Resolve<IController>(controllerClassName); 
      this.RequestContext = context; 
     } 
     else 
     { 
      controller = base.CreateController(context, controllerName); 
     } 
     return controller; 
    } 

    public override void ReleaseController(IController controller) 
    { 
     IDisposable disposable = controller as IDisposable; 
     if (disposable != null) 
     { 
      disposable.Dispose(); 
     } 
    } 
} 

я ссылаться на это в моей Global.asax следующим образом:

protected void Application_Start() 
    { 

     ControllerBuilder.Current.SetControllerFactory(typeof(App.Util.SpringControllerFactory)); 


     RegisterRoutes(RouteTable.Routes); 
    } 
+0

, где IApplicationContext Context установлен в SpringApplicationContext? – Fabiano

Смежные вопросы