I am using MVC2 with MvcContrib HelpTester.
I have problem with testing Controllers which are in Areas.
Here is my Test class :
[TestFixture]
public class RouteTests
{
[TestFixtureSetUp]
public void Setup()
{
RouteTable.Routes.Clear();
MvcApplication.RegisterRoutes(RouteTable.Routes);
}
[Test]
public void RootMatchesHome()
{
"~/".ShouldMapTo<TradersSite.Controllers.HomeController>(x => x.Index());
}
[Test]
public void AdminProductShouldMapToIndex()
{
"~/Admin/Produit/".ShouldMapTo<TradersSite.Areas.Admin.Controllers.ProductController>(x => x.Index());
}
Here's the action Index from my ProductController in the Admin Area :
public ActionResult Index(int? page)
{
int pageSize = 10;
int startIndex = page.GetValueOrDefault() * pageSize;
var products = _productRepository.GetAllProducts()
.Skip(startIndex)
.Take(pageSize);
return View("Index", products);
}
Here is the route map in my AdminAreaRefistration :
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Admin_default",
"Admin/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
Finally here is the message I get back from MbUnit :
[fixture-setup] success
[failure] RouteTests.AdminProductShouldMapToIndex
TestCase 'RouteTests.AdminProductShouldMapToIndex' failed: Expected Product but was Admin
MvcContrib.TestHelper.AssertionException
Message: Expected Product but was Admin
Source: MvcContrib.TestHelper
StackTrace:
RouteTests.cs(44,0): at CBL.Traders.ControllerTests.RouteTests.AdminProductShouldMapToIndex()
Your area routes aren't being registered in the setup. Since you're just calling RegisterRoutes, which (by default) doesn't register areas, it's getting missed.
You can either figure a way to call AreaRegistration.RegisterAllAreas() directly (which typically gets called on app start, or you need to manually register each area you want to test. In your case, the following would work:
public void Setup()
{
RouteTable.Routes.Clear();
var adminArea = new AdminAreaRegistration();
var context = new AreaRegistrationContext("Default", RouteTable.Routes);
adminArea.RegisterArea(context);
MvcApplication.RegisterRoutes(RouteTable.Routes);
}
Related
I have a project with WebAPI controllers. I'm now adding OData controllers to it. The problem is that my OData controller has the same name as an existing WebAPI controller, and that leads to an exception:
Multiple types were found that match the controller named 'Member'. This can happen if the route that services this request ('OData/{*odataPath}') found multiple controllers defined with the same name but differing namespaces, which is not supported. The request for 'Member' has found the following matching controllers: Foo.Bar.Web.Areas.API.Controllers.MemberController Foo.Bar.Web.Odata.Controllers.MemberController
And this happens even though the controllers are in different namespaces and should have distinguishable routes. Here is a summary of the config that I have. What can I do (besides renaming the controller) to prevent this exception? I'm trying expose these endpoints as:
mysite.com/OData/Members
mysite.com/API/Members/EndPoint
It seems to me that the URLs are distinct enough that there's gotta be some way to configure routing so there's no conflict.
namespace Foo.Bar.Web.Odata.Controllers {
public class MemberController : ODataController {
[EnableQuery]
public IHttpActionResult Get() {
// ... do stuff with EF ...
}
}
}
namespace Foo.Bar.Web.Areas.API.Controllers {
public class MemberController : ApiControllerBase {
[HttpPost]
public HttpResponseMessage EndPoint(SomeModel model) {
// ... do stuff to check email ...
}
}
}
public class FooBarApp : HttpApplication {
protected void Application_Start () {
// ... snip ...
GlobalConfiguration.Configure(ODataConfig.Register);
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
// ... snip ...
}
}
public static class ODataConfig {
public static void Register(HttpConfiguration config) {
config.MapODataServiceRoute(
routeName: "ODataRoute",
routePrefix: "OData",
model: GetModel());
}
public static Microsoft.OData.Edm.IEdmModel GetModel() {
// ... build edm models ...
}
}
namespace Foo.Bar.Web.Areas.API {
public class APIAreaRegistration : AreaRegistration {
public override string AreaName {
get { return "API"; }
}
public override void RegisterArea(AreaRegistrationContext context) {
var route = context.Routes.MapHttpRoute(
"API_default",
"API/{controller}/{action}/{id}",
new { action = RouteParameter.Optional, id = RouteParameter.Optional }
);
}
}
}
If you have two controllers with same names and different namespaces for api and OData you can use this code. First add this class:
public class ODataHttpControllerSelector : DefaultHttpControllerSelector
{
private readonly HttpConfiguration _configuration;
private readonly Lazy<ConcurrentDictionary<string, Type>> _apiControllerTypes;
public ODataHttpControllerSelector(HttpConfiguration configuration)
: base(configuration)
{
_configuration = configuration;
_apiControllerTypes = new Lazy<ConcurrentDictionary<string, Type>>(GetControllerTypes);
}
public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
{
return this.GetApiController(request);
}
private static ConcurrentDictionary<string, Type> GetControllerTypes()
{
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
var types = assemblies
.SelectMany(a => a
.GetTypes().Where(t =>
!t.IsAbstract &&
t.Name.EndsWith(ControllerSuffix, StringComparison.OrdinalIgnoreCase) &&
typeof(IHttpController).IsAssignableFrom(t)))
.ToDictionary(t => t.FullName, t => t);
return new ConcurrentDictionary<string, Type>(types);
}
private HttpControllerDescriptor GetApiController(HttpRequestMessage request)
{
var isOData = IsOData(request);
var controllerName = GetControllerName(request);
var type = GetControllerType(isOData, controllerName);
return new HttpControllerDescriptor(_configuration, controllerName, type);
}
private static bool IsOData(HttpRequestMessage request)
{
var data = request.RequestUri.ToString();
bool match = data.IndexOf("/OData/", StringComparison.OrdinalIgnoreCase) >= 0 ||
data.EndsWith("/OData", StringComparison.OrdinalIgnoreCase);
return match;
}
private Type GetControllerType(bool isOData, string controllerName)
{
var query = _apiControllerTypes.Value.AsEnumerable();
if (isOData)
{
query = query.FromOData();
}
else
{
query = query.WithoutOData();
}
return query
.ByControllerName(controllerName)
.Select(x => x.Value)
.Single();
}
}
public static class ControllerTypeSpecifications
{
public static IEnumerable<KeyValuePair<string, Type>> FromOData(this IEnumerable<KeyValuePair<string, Type>> query)
{
return query.Where(x => x.Key.IndexOf(".OData.", StringComparison.OrdinalIgnoreCase) >= 0);
}
public static IEnumerable<KeyValuePair<string, Type>> WithoutOData(this IEnumerable<KeyValuePair<string, Type>> query)
{
return query.Where(x => x.Key.IndexOf(".OData.", StringComparison.OrdinalIgnoreCase) < 0);
}
public static IEnumerable<KeyValuePair<string, Type>> ByControllerName(this IEnumerable<KeyValuePair<string, Type>> query, string controllerName)
{
var controllerNameToFind = string.Format(CultureInfo.InvariantCulture, ".{0}{1}", controllerName, DefaultHttpControllerSelector.ControllerSuffix);
return query.Where(x => x.Key.EndsWith(controllerNameToFind, StringComparison.OrdinalIgnoreCase));
}
}
It drives DefaultHttpControllerSelector and you should add this line at the end of Register method inside WebApiConfig.cs file:
config.Services.Replace(typeof(IHttpControllerSelector), new ODataHttpControllerSelector(config));
Notes:
It uses controller's namespace to determine that controller is OData or not. So you should have namespace YourProject.Controllers.OData for your OData controllers and in contrast for API controllers, it should not contains OData word in the namespace.
Thanks to Martin Devillers for his post. I used his idea and a piece of his code!
You'll want to include namespace constraint on your WebAPI:
var route = context.Routes.MapHttpRoute(
name: "API_default",
routeTemplate: "API/{controller}/{action}/{id}",
defaults:new { action = RouteParameter.Optional, id = RouteParameter.Optional },
);
route.DataTokens["Namespaces"] = new string[] {"Foo.Bar.Web.Areas.API.Controllers"];
If you are getting conflicts for view controllers, you should be able to include a similar namespace constraint as:
routes.MapRoute(
name: "ViewControllers_Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional, area = "" },
namespaces: new[]{"Foo.Bar.Web.Controllers"}
);
i want to access action result in controller(my controlelr is HotelController action is Index)
(http://localhost:9001/Hotel/Index) it gives below error
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Requested URL: /Hotel/Index
Hotel controller
public class HotelController : Base.BoxyController
{
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
ViewBag.Title = "SonDakka - Otel";
}
public ActionResult Index(string culture)
{
.........
BoxyController
public class BoxyController : MainController
{
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
..........
MainController
public class MainController : SiteController
{
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
......
SiteController
[ExitHttpsIfNotRequired]
public class SiteController : Controller
{
public Account Me { get; set; }
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
.......
and this is my global.asax
using System;
using System.Data.Entity;
using System.IO;
using System.Linq;
using System.Web.Mvc;
using System.Web.Routing;
using Tourism.Data;
using Tourism.Data.Mvc.Authorization;
using Tourism.Data.Mvc.Routing;
namespace Tourism
{
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}
public static void RegisterRoutes(TourismContext db, RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
var cultures = db.Cultures.Select(c => c.Code).ToArray();
routes.MapRoute
(
"Ajax",
"{culture}/{controller}/{action}/{id}",
new { id = UrlParameter.Optional },
new { culture = new ArrayRouteConstraint(true, cultures), controller = new ArrayRouteConstraint(true, "Ajax") }
).RouteHandler = new GlobalizedRouteHandler();
routes.Add
(
"Page",
new GlobalizedPageRoute
(
"{culture}/{path}",
null,
new RouteValueDictionary { { "culture", new ArrayRouteConstraint(true, cultures) } },
new GlobalizedRouteHandler()
)
);
routes.Add
(
"Route",
new GlobalizedRoute
(
"{culture}/{path}/{slug}/{id}",
new RouteValueDictionary { { "culture", UrlParameter.Optional }, { "path", UrlParameter.Optional }, { "slug", UrlParameter.Optional }, { "id", UrlParameter.Optional } },
new RouteValueDictionary { { "culture", new ArrayRouteConstraint(false, cultures) } },
new GlobalizedRouteHandler()
)
);
}
protected void Application_Start()
{
Database.SetInitializer<TourismContext>(null);
using (var db = new TourismContext())
{
#if !DEBUG
if (!db.Database.CompatibleWithModel(true))
{
System.Web.HttpRuntime.UnloadAppDomain();
throw new Exception("Veritabanı değişikliği tespit edildi.");
}
#endif
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(db, RouteTable.Routes);
}
}
protected void Application_PostAuthenticateRequest()
{
if (Request.IsAuthenticated)
{
Context.User = System.Threading.Thread.CurrentPrincipal =
new AuthorizationPrincipal(Context.User.Identity);
}
}
}
}
Because this is due to Razor engine unable to find Thanks action in Hotel controller. You need to make a Thanks action with in Hotel controller like this:
public class HotelController : Base.BoxyController
{
public ActionResult Thanks(string culture)
{
return View();
}
}
And also make sure to create a view in Hotel folder with your html code.
Based on the route config you posted, your URL should be with culture, for example:
http://localhost:9001/en/Hotel/Index
Notice the en before Hotel. It could be any value that is valid in your database.
Edit
Orignal Title: My transaction is closed by the time it gets to my Repo. What am I doing wrong?
I got a answer to my origanl questions(I forgot to open the transaction lol). Now I am wondering if my code is automatically closing the session or if I have to somehow tell it to do this.
Hi
I am using mvc 3.0, nhibernate, fluent nhibernate and ninject 2.0
Global.asax
// Note: For instructions on enabling IIS6 or IIS7 classic mode,
// visit http://go.microsoft.com/?LinkId=9394801
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
protected void Application_Start()
{
// Hook our DI stuff when application starts
SetupDependencyInjection();
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
public void SetupDependencyInjection()
{
// Tell ASP.NET MVC 3 to use our Ninject DI Container
DependencyResolver.SetResolver(new NinjectDependencyResolver(CreateKernel()));
}
protected IKernel CreateKernel()
{
var modules = new INinjectModule[]
{
new NhibernateModule(),
new ServiceModule(),
new RepoModule()
};
return new StandardKernel(modules);
}
}
Session Factory
public class NhibernateSessionFactory
{
public ISessionFactory GetSessionFactory()
{
ISessionFactory fluentConfiguration = Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008.ConnectionString(c => c.FromConnectionStringWithKey("test")))
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<MyMaps>())
.BuildSessionFactory();
return fluentConfiguration;
}
}
Session Factory Provider
public class NhibernateSessionFactoryProvider : Provider<ISessionFactory>
{
protected override ISessionFactory CreateInstance(IContext context)
{
var sessionFactory = new NhibernateSessionFactory();
return sessionFactory.GetSessionFactory();
}
}
Nhibernate Module
public class NhibernateModule : NinjectModule
{
public override void Load()
{
Bind<ISessionFactory>().ToProvider<NhibernateSessionFactoryProvider>().InSingletonScope();
Bind<ISession>().ToMethod(context => context.Kernel.Get<ISessionFactory>().OpenSession()).InRequestScope();
}
}
Service Module
public class ServiceModule : NinjectModule
{
public override void Load()
{
Bind<ITest>().To<Test>();
}
}
Repo Module
public class RepoModule : NinjectModule
{
public override void Load()
{
Bind<IStudentRepo>().To<StudentRepo>();
}
}
HomeController
private readonly ITest test;
public HomeController(ITest test)
{
this.test = test;
}
//
// GET: /Home/
public ActionResult Index()
{
return View();
}
Test(my service layer file)
public class Test : ITest
{
private readonly IStudentRepo studentRepo;
public Test(IStudentRepo studentRepo)
{
this.studentRepo = studentRepo;
}
}
Repo
public class StudentRepo : IStudentRepo
{
private readonly ISession session;
public StudentRepo(ISession session)
{
this.session = session;
}
}
When I look through my debugger at the session that is coming into my repo. It says the session is open and connected but the (session.Transaction).IsActive = false
You're currently set up to use implicit transactions, which I don't believe are exposed through session.Transaction. Of course, Use of implicit transactions is discouraged.
Does anyone know how to use an AsyncController in a mvc application that uses Ninject for DI?
AsyncController works fine when i dont use ninject but i cant make them work together.
I added following in my sitemodule but no go.
Bind<IAsyncController>( ).To<AsyncController>( ).InSingletonScope( );
sorry for not explaining this in details.
my controller looks like this
[HandleError]
public class HomeController : AsyncController
{
public void IndexAsync( )
{
AsyncManager.OutstandingOperations.Increment( );
RssFeed feed = new RssFeed( );
feed.GetRssFeedAsyncCompleted += ( s, e ) =>
{
AsyncManager.Parameters[ "items" ] = e.Items;
AsyncManager.OutstandingOperations.Decrement( );
};
feed.GetRssFeedAsync( "http://feeds.abcnews.com/abcnews/topstories" );
}
public ActionResult IndexCompleted( IEnumerable<SyndicationItem> items )
{
ViewData[ "SyndicationItems" ] = items;
return View( );
}
}
and my global.asax looks like this
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
}
protected void Application_Start( )
{
AreaRegistration.RegisterAllAreas( );
RegisterRoutes( RouteTable.Routes );
}
}
this works fine. but as soon as i use ninject (ninject 2.0 ) i get 404 page not found error when i try to access the index page. this is how i am configuring ninject
public class MvcApplication : NinjectHttpApplication //System.Web.HttpApplication
{
#region IOC
static IKernel container;
public static IKernel Container
{
get
{
if ( container == null ) { container = new StandardKernel( new SiteModule( ) ); }
return container;
}
}
protected override IKernel CreateKernel( )
{
return Container;
}
#endregion
public static void RegisterRoutes( RouteCollection routes )
{
routes.IgnoreRoute( "{resource}.axd/{*pathInfo}" );
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
}
//protected void Application_Start()
//{
// AreaRegistration.RegisterAllAreas();
// RegisterRoutes(RouteTable.Routes);
//}
protected override void OnApplicationStarted( )
{
AreaRegistration.RegisterAllAreas( );
RegisterRoutes( RouteTable.Routes );
}
}
public class SiteModule : NinjectModule
{
public override void Load( )
{
}
}
Do i need to bind anything on my sitemodule?
BTW i am using Jeff Prosise's example which he posted in his blog Here
you can download his demo application and try Ninject-ify it :)
Any help appreciated.
It appears it's not working because the standard NinjectControllerFactory inserts a NinjectActionInvoker into the controller's ActionInvoker property. The NinjectActionInvoker is derived from ControllerActionInvoker. An AsyncController, however, uses ActionInvokers derived from AsyncControllerActionInvoker. for some reason, this causes the controller to not match the route, and it returns a 404.
The real fix would be a patch to Ninject to support construction of AsyncController with AsyncControllerActionInvokers.
However, in the meantime, here is a workaround:
in your Global.asax, add this override:
protected override Ninject.Web.Mvc.NinjectControllerFactory CreateControllerFactory()
{
return new MyNinjectControllerFactory( kernel );
}
and then add this class for MyNinjectControllerFactory:
public class MyNinjectControllerFactory : Ninject.Web.Mvc.NinjectControllerFactory
{
public MyNinjectControllerFactory( IKernel kernel ) : base( kernel ) { }
protected override IController GetControllerInstance( RequestContext requestContext, Type controllerType )
{
if ( controllerType == null )
{
// let the base handle 404 errors with proper culture information
return base.GetControllerInstance( requestContext, controllerType );
}
var controller = Kernel.TryGet( controllerType ) as IController;
if ( controller == null )
return base.GetControllerInstance( requestContext, controllerType );
//var standardController = controller as Controller;
//if ( standardController != null )
// standardController.ActionInvoker = CreateActionInvoker();
return controller;
}
}
this is a copy of the NinjectControllerFactory that leaves out the assignment of the ActionInvoker.
IF you have code that depends on dependencies being injected into your ActionFilters, you will need to create your own ActionInvoker that returns an AsyncControllerActionInvoker that uses Ninject. Look at the Ninject.Web.Mvc source for the NinjectActionInvoker.
Like dave pointed out a patch is needed for Ninject to support async controller and Remo says he'll work on it as soon as he has sometime. meantime you can use dave's workaround or try this. this is straight from horse's mouth. i posted a msg in ninject group and Remo responded with this .
AsyncControllers are currently not
supported. I'll add this as soon as I
have the time to implement it
properly. In the mean time you can use
apply the following changes to the
sources to add the support:
Make a copy of NinjectActionInvoker name it NinjectAsyncActionInvoker and
change base type to
AsyncControllerActionInvoker
Apply the following changes to NinjectControllerFactory diff --git
"a/C:\Users\REMOGL~1\AppData\Local\Temp\
\NinjectControllerFactory_HEAD.cs"
"b/C:\Projects\Ninject\
\ninject.web.mvc\mvc2\src\Ninject.Web.Mvc\
\NinjectControllerFactory.cs" index
2c225a1..3916e4c 100644
--- "a/C:\Users\REMOGL~1\AppData\Local\Temp\
\NinjectControllerFactory_HEAD.cs"
+++ "b/C:\Projects\Ninject\ninject.web.mvc\mvc2\src\
\Ninject.Web.Mvc\NinjectControllerFactory.cs"
## -53,10 +53,18 ## namespace
Ninject.Web.Mvc
if (controller == null)
return base.GetControllerInstance(requestContext,
controllerType);
var standardController = controller as
Controller;
var asyncController = controller as AsyncController;
if (asyncController != null)
{
asyncController.ActionInvoker =
CreateAsyncActionInvoker();
}
else
{
var standardController = controller as
Controller;
if (standardController != null)
standardController.ActionInvoker =
CreateActionInvoker();
}
if (standardController != null)
standardController.ActionInvoker =
CreateActionInvoker();
return controller;
} ## -69,5 +77,14 ## namespace Ninject.Web.Mvc
{
return new NinjectActionInvoker(Kernel);
}
}
///
/// Creates the action invoker.
///
/// The action invoker.
protected virtual NinjectAsyncActionInvoker
CreateAsyncActionInvoker()
{
return new NinjectAsyncActionInvoker(Kernel);
}
} } \ No newline at end of file
Remo
I am running a MVC 2 Preview and this is my first time trying to use Ninject2 MVC
There error that I am continently getting is:
An error occurred when trying to create a controller of type 'MyMVC.Controllers.EventsController'. Make sure that the controller has a parameterless public constructor.
What I have in my Global.cs is this:
public class MvcApplication : NinjectHttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("elmah.axd");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
routes.MapRoute(
"Root",
"",
new { controller = "Home", action = "Index", id = "" }
);
}
protected override void OnApplicationStarted()
{
RegisterRoutes(RouteTable.Routes);
RegisterAllControllersIn(Assembly.GetExecutingAssembly());
}
protected override IKernel CreateKernel()
{
return new StandardKernel(new ServiceModule());
}
}
internal class ServiceModule : NinjectModule
{
public override void Load()
{
Bind<IEventService>().To<EventService>();
Bind<IEventRepository>().To<EventRepository>();
}
}
And this is what my Controller looks like.
public class EventsController : Controller
{
private IEventService _eventService;
//
// GET: /Events/
public EventsController(IEventService eventService)
{
_eventService = eventService;
}
public ActionResult Index(string name)
{
return View(_eventService.GetEvent(name));
}
public ActionResult UpcomingEvents()
{
return View(_eventService.GetUpcomingEvents().Take(3).ToList());
}
}
I've not used Ninject, but I would assume you need to implement your own IControllerFactory. Until they update it to MVC 2. Then utilize that instead of RegisterAllControllersIn(..):
ControllerBuilder.Current.SetControllerFactory(new MyNinjectControllerFactory());
EDIT: Again, i'm not all that familiar with Ninject but this might work as a simple factory:
public class MyNinjectControllerFactory : DefaultControllerFactory
{
protected override IController GetControllerInstance(Type controllerType)
{
return [Container].GetInstance(controllerType) as Controller;
}
}
At the risk of stating the obvious, you should try adding a parameterless constructor to your Events Controller.
public class EventsController : Controller
{
private IEventService _eventService;
//
// Parameterless constructor, so NInject will work
public EventsController() {}
//
// Regular constructor
public EventsController(IEventService eventService)
{
_eventService = eventService;
}