【问题标题】:External Controllers and Castle外部控制器和城堡
【发布时间】:2013-01-05 16:46:03
【问题描述】:

已修复:如果其他 Joe Schmo 需要它,我会留下它。

在控制器工厂中,您需要注册控制器,以便在调用时可以找到它。 container.Kernel.AddComponent("ExternalResources", typeof(InteSoft.Web.ExternalResourceLoader.ExternalResourceController), LifestyleType.Transient); 这样做:

// Instantiate a container, taking configuration from web.config
        container = new WindsorContainer(
        new XmlInterpreter(new ConfigResource("castle"))
        );
        // Also register all the controller types as transient
        var controllerTypes = from t in Assembly.GetExecutingAssembly().GetTypes()
                              where typeof(IController).IsAssignableFrom(t)
                              select t;

        foreach (Type t in controllerTypes)
            container.AddComponentWithLifestyle(t.FullName, t,
            LifestyleType.Transient);

        // Register controllers in external assemblies
        container.Kernel.AddComponent("ExternalResources", typeof(InteSoft.Web.ExternalResourceLoader.ExternalResourceController), LifestyleType.Transient);

我正在使用MVC Resource loader 来压缩和缩小我的 CSS 和 JS。我还使用 WindsorControllerFactory 进行依赖注入。 MVC 资源加载器使用位于 InteSoft.Web.ExternalResourceLoader 命名空间中的控制器,该命名空间位于单独的程序集中。

问题似乎是 Castle 无法找到(并解决)该控制器,因为它位于不同的程序集中。我对 DI 和 Castle 还很陌生,所以我什至不知道从哪里开始。

城堡配置文件

<component id="MVCResourceLoader"
             service="System.Web.Mvc.ITempDataProvider, System.Web.Mvc"
             type="InteSoft.Web.ExternalResourceLoader.NullTempDataProvider, InteSoft.Web.ExternalResourceLoader"
             lifestyle="PerWebRequest">           
</component>

温莎控制器工厂

public class WindsorControllerFactory : DefaultControllerFactory
{
    WindsorContainer container;
    // The constructor:
    // 1. Sets up a new IoC container
    // 2. Registers all components specified in web.config
    // 3. Registers all controller types as components
    public WindsorControllerFactory()
    {
        // Instantiate a container, taking configuration from web.config
        container = new WindsorContainer(
        new XmlInterpreter(new ConfigResource("castle"))
        );
        // Also register all the controller types as transient
        var controllerTypes = from t in Assembly.GetExecutingAssembly().GetTypes()
                              where typeof(IController).IsAssignableFrom(t)
                              select t;

        foreach (Type t in controllerTypes)
            container.AddComponentWithLifestyle(t.FullName, t,
            LifestyleType.Transient);

    }
    // Constructs the controller instance needed to service each request
    protected override IController GetControllerInstance(Type controllerType)
    {
        return (IController)container.Resolve(controllerType);
    }
}

错误页面

    Server Error in '/' Application.
The type name InteSoft.Web.ExternalResourceLoader.NullTempDataProvider, InteSoft.Web.ExternalResourceLoader could not be located
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Configuration.ConfigurationErrorsException: The type name InteSoft.Web.ExternalResourceLoader.NullTempDataProvider, InteSoft.Web.ExternalResourceLoader could not be located

Source Error:

Line 23:         {
Line 24:             // Instantiate a container, taking configuration from web.config
Line 25:             container = new WindsorContainer(
Line 26:             new XmlInterpreter(new ConfigResource("castle"))
Line 27:             );


Source File: C:\Projects\CaseLogger Pro\CaseLogger.Website\WindsorControllerFactory.cs    Line: 25

Stack Trace:

[ConfigurationErrorsException: The type name InteSoft.Web.ExternalResourceLoader.NullTempDataProvider, InteSoft.Web.ExternalResourceLoader could not be located]
   Castle.Windsor.Installer.DefaultComponentInstaller.ObtainType(String typeName) +81
   Castle.Windsor.Installer.DefaultComponentInstaller.SetUpComponents(IConfiguration[] configurations, IWindsorContainer container) +132
   Castle.Windsor.Installer.DefaultComponentInstaller.SetUp(IWindsorContainer container, IConfigurationStore store) +66
   Castle.Windsor.WindsorContainer.RunInstaller() +35
   Castle.Windsor.WindsorContainer..ctor(IConfigurationInterpreter interpreter) +60
   CaseLogger.Website.WindsorControllerFactory..ctor() in C:\Projects\CaseLogger Pro\CaseLogger.Website\WindsorControllerFactory.cs:25
   CaseLogger.MvcApplication.Application_Start() in C:\Projects\CaseLogger Pro\CaseLogger.Website\Global.asax.cs:50


Version Information: Microsoft .NET Framework Version:2.0.50727.3082; ASP.NET Version:2.0.50727.3082 

如果我需要提供更多调试信息,请告诉我。

更新 如果我直接访问 url,它会返回压缩文件,例如http://localhost:3826/Shared/ExternalResource?name=MinScript&version=20080811&display=Show

【问题讨论】:

    标签: .net dependency-injection castle-windsor


    【解决方案1】:

    很可能 NullTempDataProvider 所在的程序集是 InteSoft.Web 而不是 InteSoft.Web.ExternalResourceLoader。如果是这种情况,注册应该是:

    <component id="MVCResourceLoader"
                 service="System.Web.Mvc.ITempDataProvider, System.Web.Mvc"
                 type="InteSoft.Web.ExternalResourceLoader.NullTempDataProvider, InteSoft.Web"
                 lifestyle="PerWebRequest">           
    </component>
    

    【讨论】:

      【解决方案2】:

      仅供参考,这是我使用 Castle 的 ControllerFactory:

      Why is Castle Windsor trying to resolve my 'Content' and 'Scripts' folder as a controller?

      请注意,我使用的是 Assembly.GetCallingAssembly().GetTypes(),因为我的自定义 ControllerFactory 位于单独的程序集中。如果是放在主mvc项目中,改成getExecutingAssembly()即可。

      【讨论】:

        【解决方案3】:

        我认为您无法通过调用Assembly.GetExecutingAssembly().GetTypes() 在外部组件中获得服务。

        尝试使用Assembly.LoadFrom("Assembly_Name"),然后用"ExternalResources"注册组件。

        【讨论】:

          猜你喜欢
          • 2013-05-29
          • 1970-01-01
          • 1970-01-01
          • 2010-09-21
          • 1970-01-01
          • 1970-01-01
          • 2015-06-21
          • 2019-01-17
          • 1970-01-01
          相关资源
          最近更新 更多