Tuesday, August 11, 2009

Separating MVC Projects in a WCF World

I'm working on a new ASP.NET MVC project where the business logic is all in a separate WCF services layer. Thus, our controllers orchestrate the UI and communicate to the controllers for the business logic.
Most simple MVC books and tutorials show a single project with separate folders for the Model, Views and Controllers. If you read long enough, you'll find suggestions of splitting the Model, Views and Controllers into their own projects/assembles. Normally, a strongly-typed View would depend on the Model. A Controller would prepare the Model for the View, so it too would depend on the Model. But the Model never depends on the View nor the Controller. We've attempted this on our project, but we hit a snag.
The Controller project has service references to our WCF services. Service references conveniently generate client proxies the services and their data transfer objects right inside the Controller project. These DTOs often suffice for a Model for our Views. However, there are many places where our Views need a more View-friendly Model, so we adpat some of those DTOs into UI-specific Model classes housed in our Model project.
The problem comes when our UI-specific Model needs to contain some of the DTOs. Because the UI-specific Model classes are in the Model project, but the classes our service references convienently generated for us are in the Controller project, you can't dot his without having an assembly reference from Model to Controller. This breaks the rule that the Model should not depend upon anything.
My short-term solution has been to do away with the separate Model project and just house the UI-specific Model classes in the Controller project, alongside the generated classes. I've not yet settled on a long-term solution. Splitting up the generated code (that is, splitting the generated service client and the generated data classes) seems futile. Perhaps the generated data classes shouldn' be used as a Model, but instead each one should have its own UI-specific counterpart in a separate Model project. Time to ponder...

1 comment:

TerminatorJoe said...

So did you figure out a better solution?