I have the following problem:
Under src/groovy I have class that is created in many parts of application (not like spring beans but in the runtime using new () operator)
I want to inject some grails services into all those instances, is it possible somehow without invoking constructor or setters?
Invoking constructors and setters are the only two ways to do dependency injection that I know of. You can use reflection and directly set the field value, but that eliminates any opportunity of having some logic execute when a dependency is injected.
Usually src/groovy (and src/java) classes are called directly or indirectly from an artifact (controller/service/taglib/etc.) that can use dependency injection, so it's often a simple matter of doing the DI there, and passing those Spring beans to the src/groovy classes in their constructors, via setters, or as arguments of the methods that use them.
Obviously if these classes were Spring beans there wouldn't be an issue, because Spring creates them and manages dependencies. But once you are working with a non-bean that has a bean dependency, you either have to do the work yourself, or look into an AOP-style solution, since you need to be notified somehow that there's a new instance that needs to be configured. I assume that this is doable, probably with AspectJ, but it'll probably be more work than it's worth, and add an extra layer of magic to further confuse new team members beyond the regular Grails and Groovy magic.
Related
Following the guidelines I read in:
https://www.devtrends.co.uk/blog/how-not-to-do-dependency-injection-the-static-or-singleton-container
I want to try and avoid using a service locator.
But on the other hand, I don't register all the types in the startup.cs file. I don't think this is right that all these internal types are referenced in the main startup.cs
I currently have a factory class that has a collection of builder classes.
Each builder class is in charge of creating a specific object.
I don't want to create all these builder classes in advance as I might not need to use them and creating them is a bit heavy.
I saw an example of how to achieve this in the link above. However the startup.cs class needs to know all these builders. I don't think this is appropriate, I'd rather have the factory class be the only one that is exposed to them. I was trying to understand if there is some kind of func/action method that I can inject from the startup.cs file into my factory class. This func/action will be in charge of creating/registering the builders and then I can activate this func/action within the class factory. I'd like this func/action to receive the interface/class/maybe name of the builder but using generics isn't working. I searched a lot and didn't find any solution so I assume this is not possible.
Seems I have 2 options:
1. Use service locator. This way only the factory class will know the builders. However if in the future, if I want to change the DI I need to "touch" the factory class (I'm contaminating the factory class). Wanted all the DI code to be located only in the startup.cs class.
2. Register the builders in the startup.cs but now the startup.cs is aware of the builders. This kinda couples the code, not really single role of responsibility
It would have been great to inject the factory class a func/action from the startup.cs that would do the registration but the factory class itself activates it.
Is this possible?
I want to try and avoid using a service locator
Great, because the Service Locator is an anti-patttern.
don't register all the types in the startup.cs file.
You should do your registrations in one single 'area' of your application: the start-up path. This area is commonly referred to as the Composition Root (the place where object graphs are composed).
I don't think this is right that all these internal types are referenced in the main startup.cs
No matter how you design it, the startup assembly is the most volatile part of the system and it always depends on all other assemblies in the application. Either directly or transitively (through another referenced assembly). The whole idea of Dependency Injection is to minimize the coupling between components and the way to do this is to centralize coupling by moving it to the Composition Root. By making types internal however, you are decentralizing object composition and that limits your flexability. For instance, it becomes harder to apply decorators or interceptors for those registered types and control them globally. Read this question and its two top voted answers for more information.
I don't register all the types
The concern of having a Composition Root that is too big is not a valid one. One could easily split out the Composition Root into multiple smaller functions or classes that all reside in the startup assembly. On top of that, if you read this, you'll understand that registering all types explicitly (a.k.a. "Explicit Register") is typically pointless. In that case you're probably better off in using DI without a Container (a.k.a. Pure DI). Composition Roots where all types are registered explicitly are not very maintainable. One of the areas a DI Container becomes powerful is through its batch-registration facilities. They use reflection to load and register a complete set of types in a few lines of code. The addition of new types won't cause your Composition Root to change giving you the highest amount of maintainability.
I don't want to create all these builder classes in advance as I might not need to use them and creating them is a bit heavy
Creation of instances should never be heavy. Your injection constructors should be simple and composing object graphs should be reliable. This makes building even the biggest object graphs extremely fast. Factories should be reduced to an absolute minimum.
TLDR;
Register or compose your object graphs solely in the Composition Root.
Refrain from using the Service Locator anti-pattern; Whole applications can (and should) be built purely with Constructor Injection.
Make injection constructors simple and prevent them from doing anything else than storing their incoming dependencies.
Refrain from using factories to compose services, they are not needed in most cases.
I have an abstract class AbstractTimerTask that extends TimerTask and I have a Jersey service that is going to manage these timer tasks. I will have more than one implementation of the abstract class, and I would like them all injected into the service. If possible, I would like to be able to inject them into a list of type List<AbstractTimerTask>. It is possible that one or more of the child classes will not be available, depending on which jar files I deploy to the server. I would like only the child classes that are available to be injected. For this reason, I can't just list the classes in the service class as individual dependencies and build the list myself.
Is it possible to inject multiple classes with the same parent type into a list of that parent type?
You can inject IterableProvder<AbstractTimerTask>, as seen in this answer
I am injecting all dependencies (services, context) through the contructor with the help of Ninject. The scope of all dependencies is for the current request. Everything works ok but now I want in some case to refresh/reconstruct the Entity Framework context. So basically I just want a dependency reinjected.
I could inject an UnitofWork and call some method on it to remake the context. For Entity Framework this means creating another context. But I am wondering if Ninject will be aware of this and what happens if I further need to use the context in the same request - will it use the old or new context?
To my knowledge ninject does not provide an implementation for what you specifically need.
In your case it might make sense that the client code controls the lifecycle of the ´DbContext´ explicitly. Instead of injecting the ´DbContext´ you would inject an ´IDbContextFactory´. You would need to pass the db context to everyone who will require the same instance.
I've worked on a fairly complicated SW where it was done like this.
However we've gone a step further: As a facilitation, we stored the unit of work (DataContext) in a ´ThreadLocal´. This limits your software in that you can't share the unit of work across multiple threads. However this is usually something you should not do anyway since a transaction should be as short as possible.
The benefit is that then you don't need to pass around the unit of work reference all the time, instead, you create an adapter which you can inject freely and which you use to access the current ThreadLocal's value whenever you need to access the unit of work.
You will still need to explicitly control the lifecycle of the unit of work, though. So you still need the factory which will instanciate the unit of work and assign it to the ´ThreadLocal´. At the end of the unit of work, you commit or rollback and then you reset the ´ThreadLocal´.
Also see this answer which also contains code:
How to use Ninject in a multi-threaded Windows service to get new instances of a dependency (DbContext) on every tick?
Sounds like you either need inject a DbContext factory class, or you could inject a Func< DbContext > and have Ninject resolve this as a method.
I have an MVC application with a typical architecture...
ASP.NET MVC Controller -> Person Service -> Person Repository -> Entity Framework DB Context
I am using Castle Windsor and I can see the benefit of using this along with a ControllerFactory to create controller with the right dependencies. Using this approach the Controller gets a Service injected, which in turn knows how to construct the right Repository, which in turn knows the correct DbContext to use.
The windsor config is something like this...
dicontainer = new WindsorContainer();
dicontainer.Register(Component.For<IPersonService>().ImplementedBy<PersonService>());
dicontainer.Register(
Component.For<IPersonRepository>().UsingFactoryMethod(
() => new PersonRepository(new HrContext("connectionString"))));
It this the right way to do it? I don't like the UsingFactoryMethod, but can't think of another way.
Also, what if the Repository needed a dependency (say ILogger) that was not needed by the service layer? Does this mean I have to pass the ILogger into the service layer and not use it. This seems like a poor design. I'd appreciate some pointers here. I have read loads of articles, but not found a concrete example to verify whether I am doing this right. Thanks.
I try to avoid using factory methods (as you mentioned you felt this smelled funny). To avoid this, you could create a database session object that creates a new DbContext. Then your repositories just need to get an instance of IDbSession and use its dbContext property. Then, you can also easily control the scope of the IDbSession object (don't use singleton because it's not thread safe).
I wanted to make that point so that I could make this more important point... Make your constructors take in only objects that are registered in the DI container (no options or configurations in constructors). Options and configurations should be read/writen in classes whose sole purposes it is to read/write those values. If all classes follow this model, then your DI registration becomes easy and classes can just add whatever dependencies they need in their constructors.
If you are trying to use a third party library that has options in constructors, wrap that class in your own class that has an easy to consume constructor and uses a configuration class to read the values needed to pass to the third party library. This design also introduces a layer of abstraction between your code and the third party library which can then be used to more easily swap (or stub) third party libraries when necessary.
The way I understand it, DI allows you to use an IoC container to do something like
If a constructor needs an IFoo, use a concrete class Foo : IFoo.
But how is a Mock object using Moq different? Doesn't it also use DI to create a fake Foo?
Thanks.
"Dependency Injection" refers to the general practice of supplying some external resource to an object that requires it. The external resource, or dependency, could be supplied via the object's constructor, a property or method, or even as a method parameter.
And you're right, a common practice is to use an IOC to manage the possible dependencies and supply them to their "clients".
Moq, like other mocking frameworks (or isolation frameworks) is a tool that can be used to generate fake (or stub or mock) objects that can be used as dependencies for the class you're testing. Most mocking frameworks (including, Moq, I think, but I don't use it myself) do not dictate how the fakes are passed to the class under test (TypeMock Isolator is an exception here, in that it has magic that can inject the dependencies into the class under test).
There's no reason why you couldn't use an IOC to register your Moq-created fakes and supply them to your class under test, but that really has nothing to do with Moq (or NMock or Rhino Mocks).