2012-09-05 79 views
5

控制器中的對象在運行時未被注入。使用Spring .NET向MVC控制器注入依賴項

Web.config文件:

<sectionGroup name="spring"> 
     <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core" /> 
     <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" /> 
    </sectionGroup> 

。 。 。

<!-- Spring Context Configuration --> 
<spring> 
    <context> 
     <resource uri="config://spring/objects"/> 
    </context> 
    <objects configSource="App_Config\Spring.config" /> 
</spring> 
<!-- End Spring Context Configuration --> 

Spring.config:

<?xml version="1.0" encoding="utf-8" ?> 
<objects xmlns="http://www.springframework.net"> 

    <!-- Crest is the WCF service to be exposed to the client, could not use a singleton --> 

    <object id="TestController" type="Project.Controllers.TestController, Project" singleton="false"> 
     <property name="ObjectA" ref="ObjectImpl"/> 
    </object> 

    <object id="ObjectImpl" type="Project.Code.Implementations.ClassA, Project" singleton="false" /> 

</objects> 

的TestController:

public class TestController: Controller 
    { 
     // this object will be injected by Spring.net at run time 
     private ClassA ObjectA { get; set; } 

問題:

在運行時,對象A沒有得到注入,並保持空,這 原因整個代碼中的空例外。

替代方法: 我可以手動初始化Spring對象並使用下面的代碼獲取它的對象。

 var ctx = ContextRegistry.GetContext(); 
     var objectA = ((IObjectFactory)ctx).GetObject("ObjectImpl") as ClassA; 
+1

你錯過了一些難題。請看看[這裏](http://foldingair.blogspot.hu/2010/01/springnet-and-aspmvc-getting-started.html)和[這裏](http://www.springframework.net /doc-latest/reference/html/web-mvc.html)和[這裏](http://nuget.org/packages/Spring.Web.Mvc/1.3.2)。 – nemesv

+0

@nemesv是的,你是正確的,事實證明我錯過了一塊拼圖。謝謝! –

回答

3

事實證明,我錯過了MVC的Spring實現中非常重要的一部分。

我對該問題的解決方案是通過添加實現IDependencyResolver的DependencyResolver。

DependencyResolver:

public class SpringDependencyResolver : IDependencyResolver 
{ 
    private readonly IApplicationContext _context; 

    public SpringDependencyResolver(IApplicationContext context) 
    { 
     _context = context; 
    } 

    public object GetService(Type serviceType) 
    { 
     var dictionary = _context.GetObjectsOfType(serviceType).GetEnumerator(); 

     dictionary.MoveNext(); 
     try 
     { 
      return dictionary.Value; 
     } 
     catch (InvalidOperationException) 
     { 
      return null; 
     } 
    } 

    public IEnumerable<object> GetServices(Type serviceType) 
    { 
      return _context.GetObjectsOfType(serviceType).Cast<object>(); 
    } 
} 

的Global.asax.cs:

protected void Application_Start() 
    { 
     AreaRegistration.RegisterAllAreas(); 

     FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 
     RouteConfig.RegisterRoutes(RouteTable.Routes); 

     DependencyResolver.SetResolver(new SpringDependencyResolver(ContextRegistry.GetContext())); 
    } 
+0

這將不起作用,因爲上下文在創建中,而ContextRegistry.GetContext()會拋出異常! – Tobias

1

您可以實現自己的IDependencyResolver,就像你在你的答案建議。但是請注意,自(iirc)版本1.3.1以來,Spring.NET已經內置了對asp.net mvc 2.03.0的支持。 Spring.net 2.0(pre release available on NuGet)也支持4.0版本。考慮改用這些庫。

您可能有興趣比較您的SpringDependencyResolverthe one provided by the Spring.net team

+0

感謝@Marijn的建議。你對Spring.NET內置的支持是正確的。但在我們的例子中,問題在於我們正在使用MVC4框架,而Spring.net 2.0尚未準備好發佈。因此,自定義實施更適合我們的情況。我將看看DependencyResolver [由Spring提供](https://fisheye.springsource.org/browse/spring-net/src/Spring/Spring.Web.Mvc4/SpringMvcDependencyResolver.cs?hb=true),謝謝! –

+0

我試圖使用Spring提供的依賴解析器,但在我的Global.asax(方法init,繼承自MvcApplication)「DependencyResolver。SetResolver(新的SpringDependencyResolver(ContextRegistry.GetContext()));「拋出錯誤說上下文仍在創建中。 –