1
votes

I would like to create a standalone class library project that acts as my composition root. I want to keep the concrete implementations of types out of projects where they are never intended to be used directly. This is not possible if I'm forced to construct my Ninject registrations inside my MVC web application. For example I would have to map: IAbstraction to ImplementationThatIsNotValidForDirectUseInThisLayer.

I have created the composition root specific project and added references to all my projects so that I can bind my abstractions to their corresponding concrete implementations. I have installed the Ninject.MVC5 Nuget package (and all of its dependencies) into the composition root specific project.

When I reference my composition root project in my main MVC5 web application I can set a break point on the Start and Stop methods and the code executes. This means WebActivator is correctly bootstrapping these classes at run-time.

The problem is when I hit a controller that is not parameterless I get the dreaded: "No parameterless constructor defined for this object." error message.

Why isn't Ninject being used to construct controllers and all of their dependencies? Is there some additional configuration I need to do?


I have a project reference from MyApp.WebApp to the MyApp.WebApp.CompositionRoot.Ninject project where all of my bindings are being configured.


The problem seems to occur only when the initial ASP.NET project is created from the Empty project template in Visual Studio (I'm using 2013 for what its worth) with MVC added via Nuget. If I create my ASP.NET web application using the MVC template and keep my composition root in an external class library referenced by the MVC application, the controllers are correctly constructed by Ninject. I've looked at the project created from the MVC template and the only reference that sounded potentially important that was missing was "System.Web.Abstractions. I added the reference but it did not fix the issue.

1
In what way are you referencing this "composition root" in the MVC application? Do you have any code you can show?xDaevax
Edit added to clarify where the composition only project is being referenced from.Jeremy F
Are you making some call to this "composition root" from your actual composition root in the ApplicationStart method? Also, still not clear on why you created a separate library for this instead of including it in the website. Aren't the bindings specific to the website anyway?xDaevax
I have not explicitly added any code to the MVC5 web app project. The magic works with 0 configuration of the web application using WebActivator which automatically calls a "Start" and "Stop" method when the library is dropped into the /bin folder of the executing web application. I would like to avoid defining the composition root in my web application because in my opinion it makes it easy for any developer to use concrete implementations instead of abstractions, violating the layered architecture.Jeremy F
Added additional information and findings depending on the Visual Studio ASP.NET application project template used when creating the project.Jeremy F

1 Answers

0
votes

I decided to define my Ninject modules in the separate composition root only class library project, but installed the Ninject.MVC5 Nuget package into the web application. The goal of keeping the concrete implementations unavailable to the web application is maintained, but I do have to keep some references to Ninject in the MVC web application. This is a minor issue, at least this maintains my layered architecture and guarantees that a type cannot be used where it was not intended (without adding references of course!).