is there a way to extend an abstract factory of a module and remove the extended factory? I have to do some modifications to it, but if I extend it and register my new one, the old factory is still registered, isn't it?
You could override factory with your own, but it would lead to code duplication and you would have to monitor updates made by developer of that 3rd party module.
You could use initializer but it's invoked during initialization of each service, so it may have impact on performance.
What you are looking is delegator. It's kind of wrapper for real(orginal) factory.
Here is excellent article by Marco Pivetta: Delegator Factories in Zend Framework 2
This is how he explains delegators:
A delegator factory is pretty much a wrapper around a real factory: it
allows us to either replace the real service with a "delegate", or
interact with an object produced by a factory before it is returned by
the Zend\ServiceManager.
In pseudo-code, a delegator-factory is doing following:
service = delegatorFactory(factory());
Example of Delegator Factory:
class LoggerDelegatorFactory implements DelegatorFactoryInterface
{
public function createDelegatorWithName(
ServiceLocatorInterface $serviceLocator,
$name,
$requestedName,
$callback
) {
$logger = $callback();
$logger->clearFilters();
$logger->addFormatter(new HttpRequestContextFormatter());
return $logger;
}
}
Service Manager configuration:
'delegators' => [
'DbLoggingModule\Logger' => [
'LoggerDelegatorFactory',
// can add more of these delegator factories here
],
],
Related
I've just started learning Dart and I wonder what advantages of factory constructor over standalone factory class or function?
When we add new derived class then we need to change factory method inside of our abstract class, it is fine if we have its code, but if it comes with library - factory constructor becomes useless?
Or there is some mechanism to update factory method with info about derived classes? If it so, please share an example.
factory lets you return subtypes, which is very useful.
For instance, you could have factory MyClass.empty => const _EmpytMyClass() and return a trivial implementation with no storage.
You can also use it to returned cached values if you want to have canonical instances of your class.
You can also use factory to call methods to create your instances. See here: https://github.com/dart-lang/json_serializable/blob/4033f6ad4e3c96bc2ed16d93c0995e11fcfe42df/example/lib/example.dart#L29
If I have a class that requires a dependency through its constructor:
public MyClass( IDependencyInterface dependency )
and the dependency uses a factory/builder (it is still confusing to me the distinction between the two) to set its parameters:
IDependencyInterface dependency = dependencyFactory
.ChangeSomeParameter(someValue)
.ChangeSomeOtherParameter(someOtherValue)
.Build();
How do I create the factory for MyClass without passing in other factories to instantiate the required dependancies?
public MyClassFactory
{
private SomeParam _someParam;
private IDependencyFactory _dependencyFactory;
public myClassFactory( IDependencyFactory dependencyFactory)
{
_dependencyFactory = dependencyFactory;
}
public ImyClassFactory ChangeSomeParameter(someParam)
{
_someParam = someParam;
}
public IMyClass Build()
{
Dependency dependency = _dependencyFactory
.ChangeSomeParameter( _SomeParam )
.Build();
return MyClass(dependency);
}
}
How do I prevent from having to pass the factories of the dependencies required for me to build “MyClass” when I create my MyClassFactory? Or is it correct, that you need to pass in the factories of every dependency into the factory for the class with dependencies?
P.S. I plan on making the factories singletons that are instantiated at run time and passed around. Also I am new to Dependency Injection. Please let me know if there is a better way to use factories with interfaces.
If you are new to dependency injection, I would say: you don't.
Resolving dependencies and creating the vast majority of factories is a purpose of the dependency injection service provider. You get this feature by using a dependency injection component somebody else wrote, e.g. Microsoft.Extensions.DependencyInjection.
In general, application code merely lists its dependencies, for example by merely declaring them as constructor arguments. Services don't care how they or their dependencies are created. One role of dependency injection is inversion of control which popularly said means don't call us, we'll call you. This should especially hold for constructors when talking about dependency injection.
As soon as you start breaking your head over how to create or pass around factories, you're violating several principles of good design.
Have a look at the Dependency injection in ASP.NET Core article on learn.microsoft.com. It has more useful links at the bottom of the page. It is written with writing ASP.NET Core web sites/applications in mind, but most of the article in fact deals with the principles of modern software development (such as inversion of control) that apply in general for any application.
I came across this piece of code:
public class SomeServiceFactory : ISomeServiceFactory
{
private IUnityContainer container;
public SomeServiceFactory(IUnityContainer unityContainer)
{
this.container = unityContainer;
}
public virtual ISomeService GetSomeService()
{
return this.container.Resolve<ISomeService>();
}
}
I'm trying to understand how this pattern is more useful then simply having the consumer of this factory simply be injected with ISomeService directly? Thus, become a consumer of the service itself, rather than the factory. What does this additional layer of indirection achieve, as implemented here?
I understand that if the creation of ISomeService needed more intricate logic, not achievable by container.Resolve, then definitely a factory would have been required.
Good question. Without contextual information, it's difficult to defend such a degenerate Abstract Factory.
Sometimes, the reason for this may be that the programmer writing the consumer of this factory knew that the ISomeService implementation had to be created anew for each use; perhaps that particular implementation wasn't thread-safe.
Furthermore, ISomeService might derive from IDisposable, and perhaps the client does something like this:
using (var svc = this.factory.GetSomeService())
{
// use svc here...
}
This would cause svc to be properly disposed of after use.
All of the above are leaky abstractions, but common nonetheless.
A better approach to deal with such lifetime and resource management issues is either via a Decoraptor or the Register Resolve Release pattern.
This, however, could still require you to have a class like SomeServiceFactory, but then it'd be an infrastructure component, for example supporting a Decoraptor.
Do note, however, that this particular Abstract Factory is degenerate because it takes no method arguments. An Abstract Factory with one or more method arguments, on the other hand, is a common solution to the problem of creating a polymorphic service based on a run-time value.
I'm simply looking for advice on the best way I should handle this situation.
Right now I've got several files in a folder called Service. The files contact several functions which do random things of course. Each of these files needs access to the SM Adapter.
My question is, should I implement the ServiceManagerAwareInterface in each of these files OR should I just make a new class which implements the ServiceManagerAwareInterface and just extend my classes on the new class which implements this service?
Both ways work as they should, just not sure which way would be more proper.
If you think that your system will always rely on ZF2, both approaches are equivalent.
Now from an OO design perspective, personally I have a preference for the approach in which you extend your service then implement the ServiceManagerAwareInterface. I would even use an interface for the dependency over the ServiceLocator to protect even more my classes. Why?
Extending your classes does not cost you a lot, same for making your class depending on interfaces.
Let's take this example, Imagine you did not use this approach during a ZF1 project, during which you had probably resolved your dependencies with the Zend_Registry.
Now, let's assume you moved to a ZF2 implementation, how much time you think you'll spend refactoring your code from something like Zend_Registry::get($serviceX) to $this->getServiceManager()->get($serviceX) on your Service layer?
Now Assume you had made the choice of protecting your classes, first by creating your own Service locator interface, as simple as:
public interface MyOwnServiceLocatorInterface{
public function get($service);
}
Under ZF1 you had created an adapter class using the Zend_Registry:
public class MyZF1ServiceLocator implements MyOwnServiceLocatorInterface{
public function get($service){
Zend_Registry::get($service);
}
}
Your Service classes are not coupled to the Zend_Registry, which make the refactoring much more easier.
Now, You decide to move to ZF2 so you'll logically use the ServiceManger. You create then this new Adapter class:
public class MyZF2ServiceLocator implements
ServiceManagerAwareInterface,MyOwnServiceLocatorInterface
{
private $_sm;
public function get($service){
$this->_sm->get($service);
}
public function setServiceManager($serviceManager){
$this->_sm = $serviceManager;
}
}
Again, your Service classes are not coupled to the ZF2 ServiceManger.
Now, how would look like the configuration/registration of you Service layer on the ServiceManager. Well, you'll use your Module::getServiceConfig class for that:
//Module.php
public function getServiceConfig()
{
return array(
'factories'=>array(
'My\ServiceA'=>function($sm){
return new My\ServiceA($sm->get('My\Service\Name\Space\MyZF2ServiceLocator'));
}
//Some other config
)
}
As you can see, no refactoring is needed within your Service classes as we protected them by relying on interface and using adapters. As we used a closure factory, we don't even need to extend our Service classes and implement the ServiceLocatorAwareInterface.
Now, before concluding in my previous example i have to note that I did not treat the case in which my classes are constructed via factories, however, you can check one of my previous answers that address the factory topic but also the importance of loose coupling among an application layers.
you can add initializers to do that. It can reduce repetitive injection in getting the service that pass db adapter. OR, you can set abstract_factories, it will reduce repetitive SM registration. I just posted SM Cheatsheet here, Hope helpful :)
https://samsonasik.wordpress.com/2013/01/02/zend-framework-2-cheat-sheet-service-manager/
I have a question regarding dependency injection.
say i want to create a class
call it, WebGetTask
WebGetTask would need a dependency to HttpService
bad code 1
Code:
private HttpService httpService;
...
List<WebGetTask> list = new ArrayList<WebGetTask>();
for(...)
{
list.add(new WebGetTask(httpService));
}
...
ok. i know this is bad, because httpService is injected, but its never used, except for the creation on a new WebGetTask
ok
bad code 2
Code:
private WebGetTaskFactory webGetTaskFactory;
...
List<WebGetTask> list = new ArrayList<WebGetTask>();
for(...)
{
list.add(webGetTaskFactory.newTask());
}
...
i think this is better, because we use a factory
but...
but..
from where i'm standing,
i can see that
in WebGetTaskFactory
we are still injecting a HttpService and not doing anything to it except for the sole purpose of creating a new WebGetTask
so
to recap
my question is
how do i design a factory class (WebGetTaskFactory), that creates new objects (WebGetTask) when the new objects require a dependency (HttpService) on their constructor without simply injecting and passing the dependency (HttpService) ?
or rather, is this the way to do it? if so, then it's all good, if its not, then please guide me to how to properly use DI and factory pattern.
thanks.
I'm going to assume that the code you have shown is part of a DownloadManager class, and that you inject your dependencies via the constructor. In this case, I would expect the start-up code which glues everything together to look like this:
IHttpService httpService = new HttpService();
IWebGetTaskFactory webGetTaskFactory = new WebGetTaskFactory(httpService);
IDownloadManager downloadManager = new DownloadManager(webGetTaskFactory);
The DownloadManager class only knows about the IWebGetTaskFactory interface. It does not know about IHttpService, thus satisfying the law of Demeter.
edit: After re-reading your question, it seems that you are worried that you are not "using" the HttpService in your factory, except to pass it on to a new WebGetTask. This is OK. Both WebGetTaskFactory and WebGetTask need an HttpService instance to do their job. This is not a violation of the law of Demeter.
Okay, there's nothing specifically wrong under the LoD about passing an implementation object, a "plugin" in the constructor. What's important is that the interface of the class doesn't tell you much about that implementation.
If your interface to WebGetTask depends on the exact implementation of HttpService, that violates the Law of Demeter.
The trick here is to think about the interface signature of WebGetTask. The name itself suggests that you're not quite following the Law of Demeter — or principle of least knowledge — because you're defining a class that (1) is defined as being specific for the web, and (2) is a verb instead of a noun.
Now, neither of those is necessarily wrong, but they are both "OO smells" if you will, signs that you may not be thinking object-ly enough.
So let's try "refactoring" the design. First thing, think about a GetTask that has no "web" associated with it. You can then, either at construction time or at some later time build a service object and pass it in. If it's HttpService, that's fine, but the user of your class doesn't need any information about what's under the covers.
Second thing, let's make it a noun. Call it TaskFactory — your intuition was leading you right there — with a ctor that takes an IOService, which I've just invented as being the abstract interface implemented by HttpService.
Now, you have (this is sort of Java/C++ pseudocode, don't get excited about syntax details):
class Task { ... }
class TaskFactory {
public TaskFactory(IOServer svc){...}
public Task get(){...}
}
and you use it by writing
TaskFactory fac = new TaskFactory(new HttpService());
Task tsk = fac.get();
Now, we kow the minimum about the innards of TaskFactory, the IO service, and for that matter Tasks.
There are two ways of DI: the first one is a constructor one, which is usefull when only one or two objects are injected, and a setter one (actually as many setters as needed).
If you want to use a factory method for DI than in principle its same as a constructor based one.
Example 1, for a constructor DI:
list.add( new WebGetTask( httpService ) ) ;
Example 2, for a setter DI:
WebGetTask webGetTask = new WebGetTask();
webGetTask.setHttpService(httpService);
// set other dependencies
list.add(webGetTask);
The factory method is best for when you need to use some greater logic when creating objects that may behave differently, but have the same interface, thus the LoD. Lets assume there is a DownloadManager interface implemented dynamically based on the factory parameter(s).
Example 3, creation logic encapsulated into a factory method:
public static DownloadManager createDownloadManager(HttpService httpService){
if(null!=httpService){
WebGetTask webGetTask = new WebGetTask();
webGetTask.setHttpService(httpService);
// set other dependencies
return new DownloadManagerImpl1(webGetTask);
} else {
return new DownloadManagerImpl2();
} // if-else
}