If I have a collection which contains a list of models and want to create corresponding views for each model, what is the best way to do this using IOC (inversion of control)?
I see two ways:
Use a factory pattern. I would only pass in my model collection and build views as I need them with a factory that is passed in via IOC.
Create a another class which would have a list of all the views I need, pre-built by the IOC. Then I just pick the view I want from the list.
Which way do you think is better?
If you can build the Views in advance the best solution might be to simply inject a list (IEnumerable) of all the Views into each consumer and perhaps use the Specification Pattern to select the appropriate View from that list.
If, on the other hand, you need run-time values before you can instantiate each View, a Factory is the correct solution.
Related
I have a project where the data-model and business-layer are located in two different modules. Of course, the bussiness-module has a dependency to the model-module. The entity-validation is implemented through java-validation-api annotations.
I'm wondering where I should implement the cross-entity-validation (business validation, where the relations between different entity types are validated). Currently I see the follwing options:
Create custom javax.validation.ConstraintValidators and associated annotations. Problem is, that the validator would need access to the business-services, i.e. to retrieve related entities, but the model-module should not have a dependency to the business-module.
Implement cross-entity-validation in the business-services persist/merge-methods (i.e. by using interceptors). That would be possible, but the cross-entity-validation is seperated from the entity-validation and I would like to have only one place for validation.
Which option is preferable? Are there any better suggestions?
Thanks,
Sebastian
From the ideological point of view approach 1. is better. Bean Validation is working at the level of Model (in Model-View-Controller) and it is nothing wrong if Model part talks to database. So, for instance, you can create DAOs, which can be used both by service leayer and Model validators in order to avoid code duplication.
Interceptors are also good place to validate something, but you will not be able to use full power and automaticity of Bean Validation. Probably you will need to call validate method on your model objects by hand, throw ConstraintViolationException where needed, etc. Doable, but a little bit of work. In addition some validation probably will be left in Model, so, as you've pointed out, there would be more then one place, where validation is going on.
So I would move necessary DB code to separate layer and go with option 1.
I find myself needing to have a View expose its Model and Controller references. Is this the smell of bad design? Or is this considered "safe" practice?
For example: I have a list (composed of a ListView, ListController, and ListModel) and many list items (composed of a ItemView, ItemController, and ItemModel).
When I create the ItemModel, ItemView, and ItemController for each list item, I pass the ItemView instance off to the ListView. But, at some later point, my ListController needs a reference to the corresponding ItemController instance.
So, would it be more proper to pass both the ItemView and the ItemController in to ListView::addItem(), or just pass in ItemView and expose an instance method such as ItemView::getController()?
Or doesn't it matter? Is each approach equally viable? If followed to their logical conclusion, does either tactic result in an anti-pattern?
But, at some later point, my ListController needs a reference to the corresponding ItemController instance
Why? If you're decoupling your classes properly, you shouldn't need this.
Controllers almost always address a functional domain. An example of such a domain might be "Sales" or "Admin." In addition, MVC also supports the use of "Areas," which provides an additional hierarchical level of organization.
Adding references to controllers from other controllers is at cross-purposes with this organizational structure. If you need to combine functionality to make your code more DRY, ordinary refactoring will accomplish that. You can also inherit controllers from a base class containing common functionality.
In the mvc pattern the users request shall be routed to a controller, say invoicecontroller, that has actions.
Lets say the default action, Index, returns a list of invoices; the controller then creates a model with a list of invoice objects, instantiates the correct view and injects the model into the view.
Now it is the views turn to do its magic. It renders the best view it can with the data it has, which may include routes to one or more controllers.
In NO instance should the view (or model) do business logic themselves.
That said, I totally agree with Jakub. Hope that helps.
Considering you are not actually showing any code at all.
In my opinion, you should change your design. A controller is not supposed to communicate with another controller (directly), MVC dictates it: reference.
If you need to invoke a controller action from another controller, consider using delegates or composition. Instead of directly invoking the controller action.
I am quite new to MVC. I am having the following questions, please help me clarify those questions, thanks a lot.
Q1. Where should I populate my view model? e.g. My view model is very big, and contains a lot of the dropdown listbox, multi select list and the other few complex objects. I am currently populate them inside the view model self, by passing the model through the constructor, and load all the object data within the constructor. I also see my college populate the viewmodel inside controller. so I am confusing now, coz lots of people suggest to keep the controller small and skinny.
Q2. We are using the linq2sql as data access layer, should I use the table entity in my viewmodel instead of creating separate model class? Expert said it's bad, but if create seperate model class, I basically repeat them and I also need to copy those value to linq 2sql entity every time when I want to persist data, it's not that fun, too much work.
lots of people suggest to keep the controller small and skinny.
Yes. What people mean is that the controller should not contain any logic, except for model <-> view mapping. With model I mean the "M" in MVC.
Q2. We are using the linq2sql as data access layer, should I use the table entity in my viewmodel instead of creating separate model class? Expert said it's bad, but if create seperate model class, I basically repeat them and I also need to copy those value to linq 2sql entity every time when I want to persist data, it's not that fun, too much work.
No. You should not. Read my answer here: ASP.NET MVC Where to put custom validation attributes
Use a mapping framework for the model -> viewmodel conversion.
Update:
From what I understand, you suggest to assembly the viewmodel inside the controller (I mean call the business layer or repository to get my data) and use controller to call the business logic dealing with the data, am I right?
yes. The controller is really a glue between your business layer / repositories and your views. The views (and view models) should know nothing about them and the business layer / repositories should know nothing about the controller/view.
The controller was created for just that purpose. To create an abstraction between the user interface layer and the lower layers. Hence the only code that should exist in the controller is to make that possible (and therefore following the Single Responsibility Principle)
If you start adding that logic into your view models you start to add coupling between the lower layers and the user interface layer. Doing any changes in the lower layers will therefore also affect all your view models (instead of just the controller
your viewmodel should be a poco, and should most certainly not be handling the mapping of the model. if you don't want to map your model to your viewmodel in the controller i would suggest you look at something like automapper. it makes it easy.
once you've mapped from your model to your viewmodel, any extra properties that need to be set such as your lists should be set in the controller.
as i stated previously, definitely don't tie your viewmodel to your current orm or table structure. you never know what might need to be refactored, and if you can handle it via an automapper mapping instead of changing your view and viewmodel then you've saved yourself a significant amount of time.
I'm trying to make a dynamic menu function in an ASP.NET MVC 3 website - and I'd like to know if there is a built-in way to get all of the Controllers and Actions at runtime?
I realize that I can use reflection to find all public methods on my controllers, but this doesn't exactly give me the relative URL that I should put in the <a href="..."> tag.
Also, I'm going to be decorating some of the 'actions' with filter attributes that dictate whether the current user can see/goto those pages. So it would be best if I had access to the filters as well so as to be able to call the IsAccessGranted() method.
What are my options? What is the best option?
I actually just did that two weeks ago.
var q = from type in Assembly.GetExecutingAssembly().GetTypes()
where type.IsClass && type.Namespace != null && type.Namespace.Contains("Controller")
select type;
q.ToList().ForEach(type => doWhatYouNeedToDo(type)));
if you are using T4MVC, then this script will return double entries. To avoid this, work with
&& !type.Name.Contains("T4MVC")
In the method doWhatYouNeedToDo() you could transform the Type object into a DTO that suits your needs and add work further with it.
As far as your dynamic menu is concerned, you could use the MvcSiteMapProvider and implement your own dynamic sitemapprovider with it, so you are no longer bound to the static sitemap xml file.
But reflection is quite slow in .NET, so you might want to store representations of your controllers and method in the database.
There is no built in mechanism in MVC to enumerate over all of your controllers and actions. You would have to use reflection to inspect all the loaded types and look at their methods and the associated attributes. Of course this is assuming that you are using the default reflection-based action dispatching mechanism. Since MVC's pipeline can be replaced in a number of places its easy to inject a system for invoking action methods that is not based on CLR classes and methods. But if you have complete control over your application than you life is easier.
Try TVMVC. You'll still have to use reflection, but the t4 templates will generate a class that's easier to iterate over.
I'm just learning MVC so you could find my question rather strange...
My Controller have access to different shared objects through Container object passed to Controller's constructor. To access shared objects I should do $this->container->db to access Database adapter or $this->container->memcache to access Memcached adapter. I want to know should I put View object into Container with shared objects or no?
From one side it is really comfortable to take view from this container, but this way I couldn't create multiple Views instances (for example, every time I'm calling Controller's method from View I should have one more View instance). What is the solution? How should I pass View object into Controller and/or how should I create new View instances from Controller?
Thank you!
If you want that DI experience, do it on views as well, but I don't know if it really helps you anyway. Never call controller methods from views. Instead write some partial view methods and call them from views, which define the page layout (something similar to what Rails does).
IMHO if you want to get on MVC gradually, start from core principles and iteratively get to details, but don't learn architectural/design pattern as MVC by parts - architecture, design, the whole matters:)
Hmm, maybe try implementing caching for static parts. IMHO try inserting cacher object (through DI) to controller, and let that object decide if you want to send cached partial view or instantiate a new one. If you want to cache data from db, use the same pattern from controller towards models, so whenever in a controller you need models, ask db cacher object (same DI principle). Is it clear enough?