How to make factories work well with Guice? - dependency-injection

In my project, I use dependency injection everywhere, and I use ad hoc factories for two cases. First, when I want to control exactly when an instance is created, I inject a factory instead of an instance:
// WidgetA must be created before WidgetB, because of the side-effects
// on the container.
WidgetAFactory.make(container);
WidgetBFactory.make(container);
The other case is when the constructor takes a mix of injectable values and runtime values. Instead of using:
#Inject
WidgetC(
Container,
#WidgetCFont Font,
#WidgetCColor Color,
#Named("flag") String flag) {
...
}
I use:
#Inject
WidgetCFactory(
#WidgetCFont Font font,
#WidgetCColor Color color,
#Named("flag") String flag) {
...
}
WidgetCFactory.make(Container container) {
return new WidgetC(container, font, color, flag);
}
But I am being hit by two limitations with my use of factories:
In my first exanple, I also need WidgetA to be a #Singleton that will be needed by other #Injected constructors. So far, my solution is to store the instance I created when calling the factory, and #Provides it for others to use. Is there a way to give the control of this singleton back to guice without having to maintain that instance myself?
In my second example, managing the injected dependencies is a mess: the WidgetCFactory has to call the WidgetC constructor with a long list of injected values, that has to be updated for each change in the dependencies, with no annotation checks. Is there a way to provide Guice with the runtime parameter, and let it deal with the other dependencies?
It feels like for both cases, I could use a child injector that would be given the runtime value, and let Guice be the factory:
public static class WidgetCFactory {
private final Injector injector;
#Inject
public WidgetCFactory(Injector injector) {
this.injector = injector;
}
public WidgetC make(Container container) {
Injector childInjector = injector.createChildInjector(new AbstractModule() {
#Override protected void configure() {
bind(Container.class).toInstance(container);
}
});
return childInjector.getInstance(WidgetC.class);
}
}
But I don't find a lot of cases of people doing this. Is it because it's too heavy, or outside the good practices of dependency injection? What would be a better way?

Mixing injected and runtime values means you should look into "assisted injection", which lets you declare certain injected values to be provided at runtime by the callsite, and for a factory to be generated which will expose only those as a parameter. From https://github.com/google/guice/wiki/AssistedInject, you'll want to install a module for each type to be handled in this way, something like
// this goes in your existing Module.configure()
install(new FactoryModuleBuilder()
// you can add more than one type here in this way
.implement(WidgetC.class, WidgetC.class)
.build(WidgetFactory.class));
//...
public interface WidgetFactory {
// you can add more than one method here
WidgetC createWidgetC(Container container);
}
#AssistedInject
WidgetC(
#Assisted Container,
#WidgetCFont Font,
#WidgetCColor Color,
#Named("flag") String flag) {
...
}
Note especially the change to the WidgetC constructor, both the different annotation on the constructor (since it is not in fact safe to construct via normal injection) and on the Container parameter (which will be provided by the factory, not the IoC container.
To make WidgetA a singleton, you can either decorate the type with #Singleton, or bind it in your configure() method:
bind(WidgetA.class).in(Singleton.class);
As written, it will be lazily created - it will only exist after it is first requested, but then every time it is requested, it will be the same instance and will not be created from scratch.

To echo Colin's correct answer, Assisted Injection is the way to go, and Guice has offered Assisted Injection (through a separate dependency/JAR) since 2.0. You can read more about Guice's implementation on the Guice wiki AssistedInject page, but I wouldn't have anything example-wise beyond what Colin wrote.
One alternative you can consider is in AutoFactory, which code-generates factory implementations for you. (It's part of Google Auto, a suite of code generators for Java that creates annotation implementations, services, immutable value objects, and factories.) It's the de facto standard for Dagger, but applies to any JSR-330 framework including Guice.
Regarding your question #1, I'll diverge from Colin to say that what you're looking for is inherently somewhat dangerous: If #Singleton objects exist for the lifetime of your app, but your WidgetA Factory takes a Container, then it is possible for your WidgetA to exist before your Container is ready or for it to exist after your Container is destroyed.
If your WidgetA Container is also #Singleton, then you can create WidgetA without a Factory, and everything goes well: You can skip the Factory, bind the Container, bind WidgetA normally, and inject a Provider<WidgetA> (available without extra configuration) to delay the creation of WidgetA until you're ready.
If your real request is for WidgetA to exist exactly as long as the Container exists, but for WidgetA/B/C to all use the same Container and WidgetA for that time, you can consider a child injector where you bind your Container and Widgets. This way each Container gets its own WidgetA, each injection of WidgetA is consistent within that container, and you'll dispose of the WidgetA when you get a new Container. Of course, if your Container only starts being available after your Injector is working and is consistent after that, you can use that child injector as your main injector and have WidgetA work after that.
If your WidgetA depends on a Container that doesn't start off as available, be careful: That might be a "scope-widening injection", because your Container will live on as #Singleton within WidgetA even if it would otherwise be garbage-collected. This could be a memory leak at best, and could cause weird errors where multiple Containers exist within your application. You could use a stateful Module as you've been using, but in any case be very careful.

Related

How to enable Serilog minimum level overrides without particular convention of calling ForContext?

This article on Serilog minimum level overrides states:
The first argument of Override is a source context prefix, which is normally matched against the namespace-qualified type name of the class associated with the logger.
For this so-called "normal" behavior, wouldn't I need to manually set the .ForContext<>() differently for each class my logger is called from? In other words, how are namespace-specific minimum log levels supposed to work without a specific convention of how .ForContext is set?
If that makes sense, then how can I set ForContext automatically without calling it with a different argument everywhere?
For this so-called "normal" behavior, wouldn't I need to manually set
the .ForContext<>() differently for each class my logger is called
from?
Yes, you would. A common way of doing it is by using the Log.ForContext<T>() on each class, in a member variable that gets shared across the different methods of your class (so that all logs get written with the same context). e.g.
public class SomeService
{
private readonly ILogger _log = Log.ForContext<SomeService>();
// ...
}
public class SomeRepository
{
private readonly ILogger _log = Log.ForContext<SomeRepository>();
// ...
}
If you are using an IoC container such as Autofac, you can have the .ForContext<>() call happen automatically when classes are resolved by the IoC container (by using constructor injection, for example).
If you are using Autofac specifically, you could use AutofacSerilogIntegration that takes care of that. There might be similar implementations for other IoC containers (or you'd have to implement your own).
If you are using Microsoft's Generic Host, then you'll need to configure it to use a custom ServiceProviderFactory which will be responsible for creating the instances and making the call to .ForContext<>()... An easy route is to integrate Autofac with Microsoft's Generic Host and then leverage the AutofacSerilogIntegration I mentioned above.

Dependency Injection and/vs Global Singleton

I am new to dependency injection pattern. I love the idea, but struggle to apply it to my case. I have a singleton object, let’s call it X, which I need often in many parts of my program, in many different classes, sometimes deep in the call stack. Usually I would implement this as a globally available singleton. How is this implemented within the DI pattern, specifically with .NET Core DI container? I understand I need to register X with the DI container as a singleton, but how then I get access to it? DI will instantiate classes with constructors which will take reference to X, that’s great – but I need X deep within the call hierarchy, within my own objects which .NET Core or DI container know nothing about, in objects that were created using new rather than instantiated by the DI container.
I guess my question is – how does global singleton pattern aligns/implemented by/replaced by/avoided with the DI pattern?
Well, "new is glue" (Link). That means if you have new'ed an instance, it is glued to your implementation. You cannot easily exchange it with a different implementation, for example a mock for testing. Like gluing together Lego bricks.
I you want to use proper dependency injection (using a container/framework or not) you need to structure your program in a way that you don't glue your components together, but instead inject them.
Every class is basically at hierarchy level 1 then. You need an instance of your logger? You inject it. You need an instance of a class that needs a logger? You inject it. You want to test your logging mechanism? Easy, you just inject something that conforms to your logger interface that logs into a list and the at the end of your test you can check your list and see if all the required logs are there. That is something you can automate (in contrast to using your normal logging mechanism and checking the logfiles by hand).
That means in the end, you don't really have a hierarchy, because every class you have just gets their dependencies injected and it will be the container/framework or your controlling code that determines what that means for the order of instantiation of objects.
As far as design patterns go, allow me an observation: even now, you don't need a singleton. Right now in your program, it would work if you had a plain global variable. But I guess you read that global variables are "bad". And design patterns are "good". And since you need a global variable and singleton delivers a global variable, why use the "bad", when you can use the "good" right? Well, the problem is, even with a singleton, the global variable is bad. It's a drawback of the pattern, a toad you have to swallow for the singleton logic to work. In your case, you don't need the singleton logic, but you like the taste of toads. So you created a singleton. Don't do that with design patterns. Read them very carefully and make sure you use them for the intended purpose, not because you like their side-effects or because it feels good to use a design pattern.
Just an idea and maybe I need your thought:
public static class DependencyResolver
{
public static Func<IServiceProvider> GetServiceProvider;
}
Then in Startup:
public void Configure(IApplicationBuilder app, IServiceProvider serviceProvider)
{
DependencyResolver.GetServiceProvider = () => { return serviceProvider; };
}
And now in any deed class:
DependencyResolver.GetServiceProvider().GetService<IService>();
Here's a simplified example of how this would work without a singleton.
This example assumes that your project is built in the following way:
the entry point is main
main creates an instance of class GuiCreator, then calls the method createAndRunGUI()
everything else is handled by that method
So your simplified code looks like this:
// main
// ... (boilerplate)
container = new Container();
gui = new GuiCreator(container.getDatabase(), container.getLogger(), container.getOtherDependency());
gui.createAndRunGUI();
// ... (boilerplate)
// GuiCreator
public class GuiCreator {
private IDatabase db;
private ILogger log;
private IOtherDependency other;
public GuiCreator(IDatabase newdb, ILogger newlog, IOtherDependency newother) {
db = newdb;
log = newlog;
other = newother;
}
public void createAndRunGUI() {
// do stuff
}
}
The Container class is where you actually define which implementations will be used, while the GuiCreator contructor takes interfaces as arguments. Now let's say the implementation of ILogger you choose has itself a dependency, defined by an interface its contructor takes as argument. The Container knows this and resolves it accordingly by instantiating the Logger as new LoggerImplementation(getLoggerDependency());. This goes on for the entire dependency chain.
So in essence:
All classes keep instances of interfaces they depend upon as members.
These members are set in the respective constructor.
The entire dependency chain is thus resolved when the first object is instantiated. Note that there might/should be some lazy loading involved here.
The only places where the container's methods are accessed to create instances are in main and inside the container itself:
Any class used in main receives its dependencies from main's container instance.
Any class not used in main, but rather used only as a dependency, is instantiated by the container and receives its dependencies from within there.
Any class used neither in main nor indirectly as a dependency somewhere below the classes used in main will obviously never be instantiated.
Thus, no class actually needs a reference to the container. In fact, no class needs to know there even is a container in your project. All they know is which interfaces they personally need.
The Container can either be provided by some third party library/framework or you can code it yourself. Typically, it will use some configuration file to determine which implementations are actually supposed to be used for the various interfaces. Third party containers will usually perform some sort of code analysis supported by annotations to "autowire" implementations, so if you go with a ready-made tool, make sure you read up on how that part works because it will generally make your life easier down the road.

How to inject an e4view with Guice injection

I am working on an existing Eclipse RCP based on Luna which consists of 99% 3.x API. We want to change this in an ongoing process; so when I was given the task of creating a new view, I wanted to use the new (in Luna, anyways) e4view element for the org.eclipse.ui.views extension point.
My problem is that part of the RCP uses xtext and thus, several components are available by using Guice.
I am now stranded with something like this
public class MyViewPart
{
#Inject // <- should be injected via Guice (I used #com.google.inject.Inject, otherwise E4DI would complain)
ISomeCustomComponent component;
#PostConstruct // <- should be called and injected via E4 DI
public void createView(Composite parent)
{
// ...
}
}
To get this injected with Guice, I would usually use an AbstractGuiceAwareExecutableExtensionFactory (as usually done in Xtext contexts) like this:
<plugin>
<extension
point="org.eclipse.ui.views">
<e4view
class="my.app.MyExecutableExtensionFactory:my.app.MyViewPart"
id="my.app.view"
name="my view"
restorable="true">
</e4view>
</extension>
</plugin>
But I did not expect this to work, because I thought it would bypass the E4 mechanism (actually, it seems to be the other way round and the e4view.class element seems to ignore the extension factory and just uses my.app.MyViewPart to inject it with E4DI. To be sure, I have set a class loading breakpoint to MyViewPart which is hit from ContextInjectionFactory.make()).
As I said, I didn't expect both DI frameworks to coexist without conflict, so I think the solution to my problem would be to put those object which I need injected into the E4 context.
I have googled a bit but I have found multiple approaches, and I don't know which one is the "correct" or "nice" one.
Among the approaches I have found, there are:
providing context functions which delegate to the guice injector
retrieving the objects from guice and configure them as injector bindings
retrieving the objects from guice, obtain a context and put them in the context
(The first two approaches are mentioned in the "Configure Bindings" section of https://wiki.eclipse.org/Eclipse4/RCP/Dependency_Injection)
And of course I could get the objects from Guice in the MyViewPart implementation, but that's not what I want...
[Edit:] In the meantime I have explored the options above a bit more:
Context Functions
I tried to register the context functions as services in the Bundle Activator with this utility method:
private void registerGuiceDelegatingInjection(final BundleContext context, final Class<?> clazz)
{
IContextFunction func = new ContextFunction()
{
#Override
public Object compute(final IEclipseContext context, final String contextKey)
{
return guiceInjector.getInstance(clazz);
}
};
ServiceRegistration<IContextFunction> registration =
context.registerService(IContextFunction.class, func,
new Hashtable<>(Collections.singletonMap(
IContextFunction.SERVICE_CONTEXT_KEY, clazz.getName()
)));
}
and called registerGuiceDelegatingInjection() in the BundleActivator's start() method for each class I needed to be retrieved via Guice.
For some reason, however, this did not work. The service itself was registered as expected (I checked via the OSGi console) but the context function was never called. Instead I got injection errors that the objects could not be found during injection. Maybe the context functions cannot be contributed dynamically but have to be contributed via declarative services, so they are known as soon as the platform starts?
(Answer here is: yes. As the JavaDoc to IContextFunction says: Context functions can optionally be registered as OSGi services [...] to seed context instances with initial values. - and since the application context already exists when my bundle is started, the dynamically registered service is not seen by the ContextFactory in time).
Injector Bindings
I quickly found out that this solution does not work for me, because you can only specify an interface-class to implementation-class mapping in the form
InjectorFactory.getDefault().addBinding(IMyComponent.class).implementedBy(MyComponent.class)
You obviously cannot configure instances or factories this way, so this is not an option, because I need to delegate to Guice and get Guice-injected instances of the target classes...
Putting the objects in the context
This currently works for me, but is not very nice. See answer below.
[Edit 2:] As I have reported, putting the objects in the (application) context works for me. The downside is that having the objects in the application context is too global. If I had two or more bundles which would require injection of object instances for another DSL, I would have to take care (e.g., by using #Named annotations) to not get the wrong instance injected.
What I would like better is a way to extend the Part's context with which my e4view is created and injected directly. But so far I have not found a way to explicitly target that context when putting in my instances ...
Thanks for any further hints...
Try the processor mechanism of E4: You should be using a (Pre or Post) Processor (along with the PostContextCreate annotation) to register your POJOs into the (global) IEclipseContext.
The solution that worked for me best so far was getting the IEclipseContext and put the required classes there myself during the bundle activator's start() method.
private void registerGuiceDelegatingInjection(final BundleContext context, final Class<?> clazz)
{
IServiceLocator s = PlatformUI.getWorkbench();
IEclipseContext ctx = (IEclipseContext) s.getService(IEclipseContext.class);
ctx.set(clazz.getName(), guiceInjector.getInstance(clazz));
}
This works at least for now. I am not sure how it works out in the future if more bundles would directly put instances in the context; maybe in the long-term named instances would be needed. Also, for me this works, because the injected objects are singletons, so it does not do any harm to put single instances in the context.
I would have liked the context function approach better, but I could not get it to work so far.

The benefits and correct usage of a DI Container

I'm having troubles getting the advantage of a IoC (DI) container like Ninject, Unity or whatever. I understand the concepts as follows:
DI: Injecting a dependency into the class that requires it (preferably via constructor injection). I totally see why the less tight coupling is a good thing.
public MyClass{
ISomeService svc;
public MyClass(ISomeService svc){
svc = svc;
}
public doSomething(){
svc.doSomething();
}
}
Service Locator: When a "container" is used directly inside the class that requires a dependancy, to resolve the dependancy. I do get the point that this generates another dependancy and I also see that basically nothing is getting injected.
public MyClass{
public MyClass(){}
public doSomething(){
ServiceLocator.resolve<ISomeService>().doSomething();
}
}
Now, what confuses me is the concept of a "DI container". To me, it looks exactly like a service locator which - as far as I read - should only be used in the entry point / startup method of an application to register and resolve the dependancies and inject them into the constructors of other classes - and not within a concrete class that needs the dependancy (probably for the same reason why Service locators are considered "bad")
What is the purpose of using the container when I could just create the dependancy and pass it to the constructor?
public void main(){
DIContainer.register<ISomeService>(new SomeService());
// ...
var myclass = new MyClass(DIContainer.resolve<ISomeService>());
myclass.doSomething();
}
Does it really make sense to pass all the dependancies to all classes in the application initialization method? There might be 100 dependancies which will be eventually needed (or not) and just because it's considered a good practice you set create them in the init method?
What is the purpose of using the container when I could just create the dependancy and pass it to the constructor?
DI containers are supposed to help you create an object graph quickly. You just tell it which concrete implementations you want to use for which abstractions (the registration phase), and then it can create any objects you want want (resolve phase).
If you create the dependencies and pass them to the constructor (in the application initialization code), then you are actually doing Pure DI.
I would argue that Pure DI is a better approach in many cases. See my article here
Does it really make sense to pass all the dependancies to all classes in the application initialization method? There might be 100 dependancies which will be eventually needed (or not) and just because it's considered a good practice you set create them in the init method?
I would say yes. You should create the object graph when your application starts up. This is called the composition root.
If you need to create objects after your application has started then you should use factories (mainly abstract factories). And such factories will be created with the other objects in the composition roots.
Your classes shouldn't do much in the constructor, this will make the cost of creating all the dependencies at the composition root low.
However, I would say that it is OK to create some types of objects using the new keyword in special cases. Like when the object is a simple Data Transfer Object (DTO)

IoC - Autowiring for objects that are created inside of components

What bothers me about IoC and autowiring is the usability of IoC for objects that are created.
Lets say I have the a static Utils class, that is used across the system. When I decided to use IoC and DI, I easily changed Utils to be non-static and have all my components receive its instance.
However, auto-wiring works well only for components that are created during bootstrap, for objects that are created during run-time or as response of user operations, and that use Utils, auto-wiring doesn't work. Instead, I have to manually pass instance of Utils to every instance of every object that is created during runtime.
The only way around it that I can see is using the anti-pattern of passing the IoC container around, which I certainly wouldn't want to do.
Is there another way? Or am I forced to pass Utils manually around to every instance and class?
Note: This isn't a question of design. Sure, I could minimize the usage of this metaphorical Utils in various ways, but in many situations it is unavoidable.
The only way around it that I can see is using the anti-pattern of
passing the IoC container around, which I certainly wouldn't want to
do.
The answer is simply: use an abstract factory.
By defining the factory interface in the application and the factory implementation in the Composition Root (your bootstrapper code) you can prevent using the Service Locator anti-pattern. This factory implementation can hold a reference to the container and call it to request instances. Because that implementation is part of your bootstrapping logic, that implementation is a infrastructure component, and you are not using it as a service locator.
Example:
public interface IUnitOfWorkFactory
{
IUnitOfWork CreateNew();
}
Implementation in composition root:
internal class SimpleInjectorUnitOfWorkFactory
: IUnitOfWorkFactory
{
private readonly SimpleInjector.Container container;
public SimpleInjectorUnitOfWorkFactory(Container container)
{
this.container = container;
}
public IUnitOfWork CreateNew()
{
return this.container.GetInstance<IUnitOfWork>();
}
}

Resources