In Zendframework 1 we use init() method for initialize stuff in controller. I saw that this is taken out from zenframework 2. Why? and what is the best way to achieve same thing in zf 2. I am upgrading my previous project developed in zf1 and I can see things has changed a lot in zf2 as compare to zf1.
Is there anyother change in zf2, they way we use other methods such as preDispatch() and postDispatch() in zf1?
Anyone has gone through this?
In zf2 controllers are instantated by the ControllerLoader, which is a subclass of the ServiceManager. If you need to initalize a controller, either use a Factory, or __construct. Use __construct for simpile initalizations, and use a Factory if the controller consumes other objects that need to be injected.
preDispatch and postDispatch are also gone in favour of the new events system. To get the same result in zf2, register event handlers for the disptach and render events. For a full list of mvc envents see http://akrabat.com/zend-framework-2/a-list-of-zf2-events/
Also, take a look here for an example of setting up a controller factory ZF2 how to get entity Manager from outside of controller
I think you can drop this into a controller and it will work.
public function onDispatch(MvcEvent $e)
Since OP mentions postDispatch, it's worth noting that __destruct now works in a similar manner. One big difference, though, is that execution cannot be prevented (e.g. through exit;) turing tear-down of the Object.
Related
I'm creating a windows 8 application (but I suspect that any one using Xaml can help me). It basically boils down to: a page with a list of products on it, clicking on a product opens a details page.
In my composition root I resolve the view model for the first page, and set the data context appropriately, but I'm not sure what the best practice is for passing a view model to page 2 when the user selects a product.
As far as I can tell I have the following options:-
The first viewmodel requires an abstract factory capable of creating
a view model for page 2 with a .create(product) method, this would be passed in to the first view models constructor
Have the second view model implement an interface with an product property allowing me to use property injection, and pass the second view model as a parameter to the first viewmodel.
Create a service locator which I know is considered by many to be an anti-pattern.
I'm at a bit of a loss, but I suspect the abstract factory is the right way to go, I want to get this right as the object graph is actually this (product->Step->Instruction), so any re-work could take quite a bit of time, but it basically means that my view model if I went down the abstract factory route would take three abstract factories, and the service for getting the initial list of products (and then is this a code smell given how many parameter it has!).
In the situation where you want to resolve the view-model in runtime (from code) factory is the way to go.
To make it easier I would also consider using some DI framework. I believe there won't be many of them for WinRT but autofac is supposed to work with metro.
Dependency Injection might be the way to do it if you are building something big. Personally I usually just pass the parameters in the Navigate() call and initialize the view model using these parameters in the OnNavigatedTo handler.
I want to log the calls to the action methods which is a better way, shall i use the actionfilterattribute or override the controller.
Action filter seems better and more reusable approach. You won't need to override each controller in which you wanted to log calls.
What I am trying to do is inject a component into my MVC app and make use of it from the controllers.
Currently I am not trying to use MEF for the actual controllers, but i want to import components e.g. A loggin component into the MVC app.
Where is the best place to do this?
Currently I have, directly in the controller, put my compose parts code and ILogger property, but I get the feeling this is not the best way. Seems like I should only need to call Compose once in the application.
So should it be in the global asax file that I do the compose?
If so, how do I get a handle on ILogger from my controllers? Should I have a "base" controller, where i inject ILogger into the constructor and inherit every standard controller from?
Hope that makes sense - I'm just struggling a bit with the structure of my code.
Thx
I use Log4Net and inject the logger into each controller. I dont think its a big hit when you use injection. Take a look at Ninject. It has both an MVC implementation and a logging module. The modules are loaded once in the global, then it injects the controllers. Basic DI, but do you really need more? If you create a base controller you will still have to create a ctor in each controller that can be injected.
You might create a base controller with the logging, then use property injection. I have never done this, but if all controllers use the same base it should work fine.
I'm using strongly typed views and autofac for Dependency Injection under ASP.NET MVC2 and I'm trying to get a common dynamic header via dependency injection. I.e. i want this to happen without the view having to be away of this content even existing and i was hoping to avoid static discovery of the container and manual resolution, but I can't find a way to easily inject the master or a partial view included in the master via either ctor or property injection.
I can't imagine this is an uncommon task, but all I can find in terms of methods is Controller subclassing to stuff data into untyped ViewData, subclassing ViewModels to stuff master data into the model, or static resolution, all of which I'd prefer not to use. What am I overlooking?
EDIT: As has been pointed out DI into master pages is fighting the framework. So my question is badly framed: I don't really care about DI into master pages, but I have a dynamic element in the chrome of the site, i.e. the master page. Providing it with a model shouldn't be the responsibility of each controller using that master, as it is request context, not controller context specific. I fully admit that injection directly into master pages is inappropriate. If i could register a separate master controller to be invoked in addition, that would be even better. Is that possible? Given this task of providing the master with a model independent of the controller, what is the framework appropriate approach? Or does shared content in MVC require that each Controller has to know about that content?
You could use child actions.
Controller:
public class MyHeaderController: Controller
{
private readony IRepository _repository;
public MyHeaderController(IRepository repository)
{
_repository = repository;
}
[ChildActionOnly]
public ActionResult Index()
{
var model = _repository.GetSomeModel();
return PartialView(model);
}
}
And somewhere in your master page include it:
<div><%= Html.Action("Index", "MyHeader") %></div>
Your problems stem from confusing the term Dependency Injection, and fighting how the ASP.NET MVC framework works.
Also, you are using the term Dependency Injection in the wrong context. You are trying to use a hammer as a chisel.
MasterPages and views in ASP.NET MVC are intended to be used as templates. As stated in the other answer, child actions will solve your problem.
For future reference:
Dependency Injection refers to a means to configure what parameters to inject into class constructors, and have this done for you automatically, overriding some of the frameworks defaults. The purpose for this is to decouple components, so that they become more reusable, more testable, more unitary, amongst other good things.
DI refers to, and solves, a code issue, not a UI issue.
What you are trying to do is simply not possible. Ie, inject via constructors and properties a "dependency" into a masterpage. Again, MasterPages are intended by ASP.NET MVC to be used as just templates. They have no code behind class to instantiate via a constructor that would allow dependencies to be injected into it.
In other words, you are fighting the framework, which means you don't understand it.
If this sounds like nitpicking, I think this has to be highlighted as otherwise, you are confusing yourself and others who read this thread in the future.
I am trying to refactor my Catalyst application and I would like to introduce a common base class for my controllers. This base controller would load some data and put some other data into the stash for every request. I have got some trouble getting to the stash. Simple solution would be to implement a default auto action in the base controller. This works, but I have to remember to always call the super auto in the derived controllers. This is easy to forget, is there a better solution? In other words: Is there a simple way to tap into the request processing that wouldn’t be so easy to break in the derived controllers?
I don't think you need inheritance in order to accomplish your goal. You might have other reasons why inheritance is a good idea for your application, but it seems as a rule that inheritance is generally overused when other methods of class composition would be more appropriate.
In particular for this case, Catalyst provides for this functionality by allowing you to specify an auto method in your Root controller, which will always be invoked before the auto methods of your more particular controllers for every request. No inheritance required.