Automatically inject resources into controller - zend-framework

I'm trying to implement dependency injection in our Zend Framework project.
In previous APS.NET based projects we've used StructureMap and overwritten the DefaultControllerFactory to inject the dependencies into the controllers.
I'm not sure where to do the injection in Zend Framework? I've looked into Zend_Controller_Plugin_Abstract and Zend_Controller_Action_Helper_Abstract but none of them seems to enable me to inject into the currently instantiated controller.
I would love to be able to inject into the constructor of the current controller like i do in ASP.NET, but setters are acceptable (I guess).
Any ideas as to how to accomplish this or something similar?
Ultimately i would like to be able to do something like this:
MyController extends Zend_Controller_Action {
// private vars
[...]
public function __constructor($authenticationService, $userRepository) {
$this->_authServ = $authenticationService;
$this->_userRepo = $userRepository;
}
}
I would like to do something like i do for stuctureMap:
For(authenticationService).Use(WhatEverClass);
or maybe:
$currentController->authServ = $authenticationService;
$currentController->userRepo = $userRepository;
In short: Where can we intercept the creation of (or get the instance of) the current controller?
Similar (unanswered) question here
Thanks!
/Jon

Zend Framework lead developer Matthew Weier O'Phinney has a post that seems to address the idea of injecting resources into controllers:
A Simple Resource Injector for ZF Action Controllers

Check out also PHP-DI, this is a dependency injection library that integrates with Zend Framework. It works with annotations.
It enables you to do things like:
MyController extends Zend_Controller_Action {
/**
* #Inject
* #var MyService
*/
private $myService;
public function helloAction() {
return $this->myService->sayHello();
}
}

Related

Workflow: Creating Dependency Chain with Service Locator Pattern

I'm trying to get dependencies set up correctly in my Workflow application. It seems the best way to do this is using the Service Locator pattern that is provided by Workflow's WorkflowExtensions.
My workflow uses two repositories: IAssetRepository and ISenderRepository. Both have implementations using Entity Framework: EFAssetRepository, and EFSenderRepository, but I'd like both to use the same DbContext.
I'm having trouble getting both to use the same DbContext. I'm used to using IoC for dependency injection, so I thought I'd have to inject the DbContext into the EF repositories via their constructor, but this seems like it would be mixing the service locator and IoC pattern, and I couldn't find an easy way to achieve it, so I don't think this is the way forward.
I guess I need to chain the service locator calls? So that the constructor of my EF repositories do something like this:
public class EFAssetRepository
{
private MyEntities entities;
public EFAssetRepository()
{
this.entities = ActivityContext.GetExtension<MyEntities>();
}
}
Obviously the above won't work because the reference to ActivityContext is made up.
How can I achieve some form of dependency chain using the service locator pattern provided for WF?
Thanks,
Nick
EDIT
I've posted a workaround for my issue below, but I'm still not happy with it. I want the code activity to be able to call metadata.Require<>(), because it should be ignorant of how extensions are loaded, it should just expect that they are. As it is, my metadata.Require<> call will stop the workflow because the extension appears to not be loaded.
It seems one way to do this is by implementing IWorkflowInstanceExtension on an extension class, to turn it into a sort of composite extension. Using this method, I can solve my problem thus:
public class UnitOfWorkExtension : IWorkflowInstanceExtension, IUnitOfWork
{
private MyEntities entities = new MyEntities();
IEnumerable<object> IWorkflowInstanceExtension.GetAdditionalExtensions()
{
return new object[] { new EFAssetRepository(this.entities), new EFSenderRepository(this.entities) };
}
void IWorkflowInstanceExtension.SetInstance(WorkflowInstanceProxy instance) { }
public void SaveChanges()
{
this.entities.SaveChanges();
}
}
The biggest downside to doing it this way is that you can't call metadata.RequireExtension<IAssetRepository>() or metadata.RequireExtension<ISenderRepository>() in the CacheMetadata method of a CodeActivity, which is common practice. Instead, you must call metadata.RequireExtension<IUnitOfWork>(), but it is still fine to do context.GetExtension<IAssetRepository>() in the Execute() method of the CodeActivity. I imagine this is because the CacheMetadata method is called before any workflow instances are created, and if no workflow instances are created, the extension factory won't have been called, and therefore the additional extensions won't have been loaded into the WorkflowInstanceExtensionManager, so essentially, it won't know about the additional extensions until a workflow instance is created.

Best practice in dependency injection

This is a question about how best to do DI, so it's not tied to any particular DI/IoC framework because, well, framework should be chosen based on pattern and practice rather than the other way around, no?
I'm doing a project where repository has to be injected into services, a service may require multiple repositories and I'm curious about the pros and cons between following approaches:
Inject repositories in service constructor
public class SomeService : ISomeService
{
private IRepository1 repository1;
private IRepository2 repository2;
public SomeService(IRepository1 repository1, IRepository2 repository2)
{
this.repository1 = repository1;
this.repository2 = repository2;
}
public void DoThis()
{
//Do something with repository1
}
public void DoThat()
{
//Do something with both repository1 and repository2
}
}
Inject a custom context class that include everything any service may need but lazy instantiated (the IServiceContext will be a protected field in BaseService)
public class SomeService : BaseService, ISomeService
{
public SomeService(IServiceContext serviceContext)
{
this.serviceContext= serviceContext;
}
public void DoThis()
{
//Do something with serviceContext.repository1
}
public void DoThat()
{
//Do something with both serviceContext.repository1 and serviceContext.repository2
}
}
Inject into methods that need them only
public class SomeService : ISomeService
{
public void DoThis(IRepository1 repository1)
{
//Do something with repository1
}
public void DoThat(IRepository1 repository1, IRepository2 repository2)
{
//Do something with both repository1 and repository2
}
}
Some pointers would be appreciated, moreover what're the aspects that I should consider in evaluating alternative like these?
The preferred way of injecting dependencies is Constructor Injection.
Method Injection is less ideal, because this will quickly result in having to pass around many dependencies from service to service and it will cause implementation details (the dependencies) to leak through the API (your method).
Both options 1 and 2 do Constructor Injection, which is good. If you find yourself having to inject too many dependencies in a constructor, there is something wrong. Either you are violating the Single Responsibility Principle, or you are missing some sort of aggregate service, and this is what you are doing in option 2.
In your case however, your IServiceContext aggregate service is grouping multiple repositories together. Many repositories behind one class smells like a unit of work to me. Just add a Commit method to the IServiceContext and you will surely have a unit of work. Think about it: don't you want to inject an IUnitOfWork into your service?
The first option seems to be the most natural from a DI perpective. The service class requires both repositories to perform its function, so making them required in order to construct an instance makes sense semantically (and practically).
The second option sounds a bit like Service Location, which is generally considered an anti-pattern (see http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx). In a nutshell, it creates implicit dependencies, where explicit dependencies are always preferred.
I would do either constructor based injection or property based injection. I would not pass in a context that contains the dependencies unless that context is serving some other purpose.
I prefer constructor based injection for required dependencies, as it makes it super easy for the object creation to blow up if something is missing. I got that from here. If you are going to verify that your dependencies are met, then you have to do it with constructor based injection, since there is no way to tell which setter is the last setter to be fired.

Dependency Injection/Property Injection on an asp.NET MVC 2 ActionFilter: Help!

I've been trying to wrap my head around the topics posted at this similar question:
Is it possible to use Dependency Injection/IoC on an ASP.NET MVC FilterAttribute?
However, I'm just not getting anywhere. Not to mention, all the solutions appear to have dependencies on other libraries which I'm not able to use (MvcContrib, Unity).
Can anyone toss together some code to explain how to make this property injection work? Or if there is another way to make this happen?
Thanks much!
Relevant code 1: Controller
namespace TxRP.Controllers
{
[GetMasterPageData]
public class BaseController : Controller
{
}
}
Relevant code 2: ActionFilter
public class GetMasterPageData : ActionFilterAttribute
{
private IEmployee emp; //<--Need to inject!
private ICache cache; //<--Need to inject!
/// <summary>
/// ActionFilter attribute which inserts the user name, access level and any error/warning messages to the MasterPage
/// Session variables which are consumed primarily by the LogOnUserControl.
/// The MasterPage will display any warning or error messages.
/// </summary>
/// <param name="filterContext"></param>
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
//Code
}
It's not possible to use DI with attributes because they are statically compiled into your classes, so nothing can ever be injected. Some people may tell you that you can use a sort of static factory to get your dependencies, but that's not Dependency Injection - that would be Service Location - which is an anti-pattern.
However, it's possible to combine DI with action filters if you abandon the idea of attributes, but not particularly easy. You'll need to create a custom IActionInvoker, although the easiest way to do that is to derive from ControllerActionInvoker and override its GetFilters method. Here's a blog post that explains how to do that for error handling - you should be able to extrapolate from that.
When you get tired of doing that I'd advice you to switch to composing cross-cutting concerns out of Decorators and other design patterns. In that way you can implement your cross-cutting concerns independently of constraining technology.

How to handle Zend_Exception's in preDispatch or init of an action when using a base controller?

As mentioned in the Zend Framework manual, I created a base controller.
Subclassing the Action Controller
By design, Zend_Controller_Action must
be subclassed in order to create an
action controller. At the minimum, you
will need to define action methods
that the controller may call.
Besides creating useful functionality
for your web applications, you may
also find that you're repeating much
of the same setup or utility methods
in your various controllers; if so,
creating a common base controller
class that extends
Zend_Controller_Action could solve
such redundancy.
But it turns out, that Exceptions are not being called properly from the base... To replicate this, create a file:
/path/to/workspace/library/Joe/Controller.php
Then:
class Joe_Controller extends Zend_Controller_Action
{
public function init()
{
Throw new Zend_Exception('test', 500);
parent::init();
}
}
Then in your controller directory, IndexController.php extends off the base:
class IndexController extends Joe_Controller
{
You will find that the exception is uncaught.
If however, you don't extend off the base controller, then throw an exception in init or preDispatch, it will be caught and forwarded to the ErrorController.
Anyone have an idea on getting the exceptions caught from the Base Controller?
Thanks.
UPDATING TO TACKLE THIS ANOTHER WAY
After looking at the various articles and official documentation on how to structure the directories, I went with putting the base controller in library/Joe/...but maybe that's part of the problem...there's no guidance in the manual on how to name and place the base controller. What do the experts with a base controller do?
Another Update
Looking at my code some more, and reading on the net, seems like people suggested in should be:
abstract class Joe_Controller_Action extends Zend_Controller_Action.
Except changing it did not solve the problem...
Now considering that there are articles suggesting to use Base Controllers including the manual, would this be considered a bug in Zend Framework?
To replicate, just throw a Zend_Exception of any kind in the base init or preDispatch. Imagine you poll the database in there, (which is what I'm doing)...and the database is down. No error controller. That's not a good situation unless I'm doing something incorrectly.
My suspicion is that this is a new bug... I don't recall this problem before Zend_Application and I've been using a base controller since ZF 1.5.
Two thoughts off the top of my head:
Controller names in the default module are usually named like SomethingController. Your name Joe_Controller suggests the module Joe and an empty controller name.
In routing/dispatch, doesn't it look for a matching action before dispatch to the controller? Since the samples have no actions, might you be triggering ControllerNotFound exception?
Just throwin' out some ideas.
in Zend philosophy, they provide the init() method to avoid the hassle of
public class Module_TotoController extends Zend_Action_Controller {
public function __construct(Zend_Controller_Request_Abstract $request, Zend_Controller_Response_Abstract $response, array $invokeArgs = array())
parent::__construct($request, $response, invokeArgs);
// some init code here
}
}
just use :
public class Module_TotoController extends Zend_Action_Controller {
public function init ()
// some init code here
}
}
Now, If you look at the Zend_Controller_Action class source, you will notice that the following methods are empty:
init()
preDispatch ()
postDispatch ()
This means, it is useless to call parent:: in your specific controller
public class Module_TotoController extends Zend_Action_Controller {
public function init ()
parent::init(); // useless ;-) but you can go for it
// some init code here
}
}
Now, if you want to put an intermediate class between Module_TotoController and Zend_Action_Controller, you expose yourself to a big hassle as:
Some controllers won't extend your "base" controller (e.g your ErrorController in your question)
so it is not a really a base of your application, is it ?
If you put some logic in your init() of that "base",
you must call the parent:: in your init(),
all the developers in the project need to be aware of that
You will ever add another little features to your "Base" controller
This will result to a big bloated file
Loading/Initializing plenty of stuff you might not really need in that lambda controller
Do you need you database on every page ?
No: doesn't a $this->_helper->connect(); look nice instead ?
Yes: use a controller plugin
This "Base" controller won't fit your other projects needs, so that class won't be reusable
Action helpers will
Controller Plugins will
Hope it makes sense
Don't go for a base or whatever controller
As documentation says :
By design, Zend_Controller_Action must be subclassed in order to create an action controller.
Agreed, this is misleading
What they meant is
class Module_TotoController extends Zend_Controller_Action {}
class Module_TotoController extends Joe_Controller is plain wrong (sorry no offence)
as you said your ErrorController can't extend your intermediate Joe_Controller class
because your exception will be thrown again in the instantiation of the ErrorController class (as excepted !!!)
The uncaught Exception error is the result of a protection to avoid loops (dig Zend\Controller\Plugin\ErrorHanlder.php line 200-ish)
If you require something to be done for every action, use a Zend_Controller_Plugin and register it with the frontController

how to use jaxws for a class referencing an interface

I have a java class which I need to annotate up for a web service. Everything is set up and compiles etc, the wsdl is generated using the maven plugin for wsprovide... the problem I have is that the class references an interface...
#WebService(name = "myWebService", targetNamespace = "......")
#SOAPBinding(style = SOAPBinding.Style.RPC)
public class MyClassImpl implements MyClass {
protected TheService m_theService;
/**
* #return the theService
*/
public TheService getTheService() {
return m_theService;
}
TheService is an interface, and so I get a JAXB error... TheService is an interface, and JAXB can't handle interfaces. The getTheService method does not need to be exposed in the web service, but I can't see how to get around it. Can anyone explain what to do in this situation?
Solved! Found this shortly after posting this message and managed to resolve my issues :-)
https://jaxb.dev.java.net/guide/Mapping_interfaces.html
You can annotate any method that does not require to be exposed with:
#WebMethod(exclude = true)
This way wsgen will ignore the method when generating the JAX-WS artifacts.