What role does the User Control has in the ASP.Net MVC?
Several developers have asked me about the use of User Controls within the ASP.Net MVC, so I decided to write down what I think about it.
A User Control is a piece of the User Interface which is sometimes created to be reused on several of Web Forms, some are created as a result from a Refactoring of the User Interface code. A User Control has a code-behind and the User Control is living its own life mostly if the Web Form and User Control is well defined. Some people tend to access the Web Form from a User Control and I think that is bad practice, it will make the User Control dependent to a specific Web Form, so a better solution is to use events which a Web Form can subscribe to, if we need to pass data from the Web Form to the User Control, we can do it by adding properties to the User Control. Now how about a User Control in the ASP.Net MVC?
As you all may know there is a View and the View has a Controller, the Controller work like a contract between the View and the Model. The Model is where we have our Business Logic and domain entities.
NOTE! I have seen several developers using the Controllers as a replacement of Business object, that is not the role of a Controller, the Business logic should be in the Model.
I will assume that a View has only one Controller and should only be dependent on one, so in the ASP.Net MVC the User Controls will take a "new" kind of role. A User Control in the ASP.Net MVC is part of the View and should reuse the same Controller as the View. If not, our View will have dependency to several different Controllers and we will need to take this into consideration when writing our test. We should try to avoid as many dependency as possible, too many dependency will make the code harder to read and maintain etc. So what role does the User Control take in a View? They will be a result of Refactoring of the User Interface code, and will more or less be like a simple "include" file used by the VIew (Like a extracted method in a Class). A User Control and a View together will create a complete View and this complete View should only work against one Controller. Some developers tend to create and use a User Control after the same pattern they are used to when they work with Web Forms. Instead of using a code-behind, they bind the User Control to it's own Controller. By doing so, a View which will use the User Control, will have a indirect dependency to several Controllers. Instead of making sure a View has its own Controller, it now has several, if we have several User Controls on the same View and all User Controls uses their own Controllers, we will sooner or later create a Death Star. If we should use a User Control in the ASP.Net MVC it's the Controller of the View which will return the Model which the User Control and View will use, right?! So it's the same Controller that should handle the User Controls actions. If we want to create a User Control and see it as a self lived unit, I think it should be important to let its own Controller give the Model to the User Control, but how it's designed today, we can't. It's the Controller used by the View which must also get the Model for the User Control.
How about reusing a User Control on different Views if they should more or less serve as a "include" file and use the same Controller as the View? For me it's all fine, because the User Control will share the same Controller as the View, and the User Control should try to avoid having its own form element. If we want to reuse a User Control on several of Views, where the User Control has its own Controller, the Controller of the View will have a indirect dependency to the User Control and suddenly the Controller of a View will have several reason to change (If the User Control need to be updated and that may lead to an update of the Controller.). To solve this, we shouldn't try to reuse a User Control as long as it can't server as a simple include of HTML element, where the User Control will not have a form element pointed to a separate Controller served only by the User Control.
I hope some of you can try to convince me if my assumptions is totally wrong, or at least you can try ;)