SportsStore:MVC编程问题[Castle WindsorControllerFactory]

时间:2009-08-16 23:18:32

标签: model-view-controller castle-windsor

所以我一直在关注Steven Sanderson的名为Pro ASP.NET MVC Framework的书,我遇到了一个例外:

No parameterless constructor defined for this object.
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.MissingMethodException: No parameterless constructor defined for this object.

Source Error:

Line 16:             HttpContext.Current.RewritePath(Request.ApplicationPath, false);
Line 17:             IHttpHandler httpHandler = new MvcHttpHandler();
Line 18:             httpHandler.ProcessRequest(HttpContext.Current);
Line 19:             HttpContext.Current.RewritePath(originalPath, false);
Line 20:         }


Source File: C:\Users\Stephen\Documents\Visual Studio 2008\Projects\SportsStore\WebUI\Default.aspx.cs    Line: 18 

这是我的WindsorControllerFactory代码:

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, Castle.Core.LifestyleType.Transient);
    }

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

我的Global.asax.cs代码:

protected void Application_Start()
    {
        RegisterRoutes(RouteTable.Routes);
        ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory());
    }

web.config值:

<configSections>
    <section name="castle"
             type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler,
                   Castle.Windsor"/>
</configSections>
<castle>
    <properties>
      <myConnStr>Server=.\SQLEXPRESS;Database=SportsStore;Trusted_Connection=yes;</myConnStr>
    </properties>
    <components>
      <component id="ProdsRepository"
                 service="DomainModel.Abstract.IProductsRepository, DomainModel"
                 type="DomainModel.Concrete.SqlProductsRepository, DomainModel">
        <parameters>
          <connectionString>#{myConnStr}</connectionString>
        </parameters>
      </component>
    </components>
</castle>

谢谢大家! -Steve

5 个答案:

答案 0 :(得分:1)

namespace WebUI
{
    public class WindsorControllerFactory:DefaultControllerFactory
    {
        WindsorContainer container;

        public WindsorControllerFactory()
        {
            container = new WindsorContainer(new XmlInterpreter(new ConfigResource("castle")));

            container.Register(AllTypes
                .FromThisAssembly()
                .BasedOn<IController>()
                .If(Component.IsInSameNamespaceAs<Controllers.ProductsController>())
                .If(t => t.Name.EndsWith("Controller"))
                .Configure(c=>c.LifeStyle.Transient.Named(c.Implementation.Name)));
        }

        protected override IController GetControllerInstance(RequestContext ctx, Type controllerType)
        {
            if (controllerType == null) { return null; }
            return (IController)container.Resolve(controllerType);            
        }
    }
 }

答案 1 :(得分:0)

我想说问题是你试图在不传递连接字符串的情况下将Linq实例化为SQL DataContext。

解决方案是声明如下:

<components>
    <component id="..." service="..." type="...">
        <parameters>
            <connectionString>blah blah blah</connectionString>
        </parameters>
    </component>
</components>

我在当前项目中使用的另一个选项是在DataContext中简单地创建一个无参数构造函数,它将简单地调用构造函数,该构造函数接受带有默认值的连接字符串,声明为静态字符串。类本身:

public partial class MyDataContext
{
    private static string standardConnectionString = "blah blah blah";

    public MyDataContext()
             : this(standardConnectionString) {}
}

它能解决你的问题吗?

答案 2 :(得分:0)

使用: protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext,Type controllerType)

Insted of: protected override IController GetControllerInstance(Type controllerType)

答案 3 :(得分:0)

我有这个问题,当你有一个没有默认构造函数的Entity类时会发生这种情况。始终创建一个不接受参数的默认构造函数。

答案 4 :(得分:0)

我只是回应这个...因为这是一个老问题(2009)。长话短说,它与Windsor的配置值有关,是在错误的配置(视图而不是基础web.config)。这解决了手头的问题。