I have a subcomponent that I need to pull something out of:
#Subcomponent(modules = {SubModule.class})
#SubScope
public interface SubComp {
// ...
Thing getThing();
}
Each time #getThing is called, I need a new instance of Thing.
Thing also has its own orbit of items that need to be created with it. Naturally, my instinct is to create another subcomponent for it:
#Subcomponent(modules = {ModuleThing.class})
#ThingScope
public interface SubCompThing {
// ...
}
But here is my dilemma: Which piece of code should actually be creating Thing?
If I put a provider into SubModule, I then need to bind that instance into SubCompThing, but I get a warning about binding multiple instances. The warning is fatal in my build, and actually states that the warning will become an error in the future:
#Module(subcomponents = {SubCompThing.class})
interface SubModule {
#Provides
static providesThing(SubCompThing.Factory thingCompFactory) {
Thing thing = new Thing();
thingComp = thingCompFactory.create(thing); // Warning about duplicate binding.
// Do some stuff with thingComp
return thing;
}
}
If I have SubCompThing create Thing directly itself, my warning turns into an error with the same problem:
#Module
interface ModuleThing {
#Provides
#ThingScope
static Thing providesThing() {
return new Thing();
}
}
#Module(subcomponents = {SubCompThing.class})
interface SubModule {
#Provides
static Thing providesThing(SubCompThing.Factory thingCompFactory) {
thingComp = thingCompFactory.create();
// Do some stuff with thingComp
return thingComp.getThing();
}
}
(Dagger compiles that Thing is bound twice, since there are two providers for it.)
How can I have my top level SubComp return new Things on demand, and have each of those Things have their own subcomponent instance associated with them?
You're going to need to use a qualifier annotation.
The root of the problem here is that subcomponents inherit bindings from their parent components, so within your deepest subcomponent SubCompThing your exposed Thing binding on your component might very well be injecting the Thing binding that you're installing in SubComp's SubModule...because Dagger doesn't know that your #Provides method in SubModule is itself about to call SubCompThing's getThing() method!
As we discussed in the comments, what you're describing is very much like Dagger's official documentation on subcomponents for encapsulation, which sneakily depicts but does not describe its reliance on a qualifier annotation:
#Subcomponent(modules = DatabaseImplModule.class)
interface DatabaseComponent {
#PrivateToDatabase Database database();
/* ^^^^^^^^^^^^ */
}
That's the disambiguating trick: Your ModuleThing should bind #Provides static #PrivateThing Thing, and your SubCompThing should expose #PrivateThing Thing getThing() such that the only bound unqualified Thing is bound in your SubModule. (Incidentally, this would allow you to inject a Thing in SubCompThing, delegating to SubModule's implementation to create a brand new SubCompThing instance from within ModuleThing's call stack.)
I've defined a cheap qualifier annotation here, but you're welcome to use #Named to prototype it.
#Qualifier #Retention(RetentionPolicy.RUNTIME) public #interface PrivateThing {}
#Module
interface ModuleThing {
#Provides
#ThingScope
#PrivateThing
static Thing providesThing() {
return new Thing();
}
}
#Subcomponent(modules = {ModuleThing.class})
#ThingScope
public interface SubCompThing {
#PrivateThing getThing();
}
At that point, your SubModule will work with no additional modifications, abstracting away the creation of Thing to a black-box implementation of SubCompThing (which I prefer slightly, such that you don't have to bring Thing's instantiation details into SubModule). It also means you can keep Thing scopeless so you can instantiate more than one of them: When you call the provider, you'll see something new. That way you can make both thing1 and thing2.
Related
I am trying to understand Components in Dagger 2. Here is an example:
#Component(modules = { MyModule.class })
public interface MyComponent {
void inject(InjectionSite injectionSite);
Foo foo();
Bar bar();
}
I understand what the void inject() methods do. But I don't understand what the other Foo foo() getter methods do. What is the purpose of these other methods?
Usage in dependent components
In the context of a hierarchy of dependent components, such as in this example, provision methods such as Foo foo() are for exposing bindings to a dependent component. "Expose" means "make available" or even "publish". Note that the name of the method itself is actually irrelevant. Some programmers choose to name these methods Foo exposeFoo() to make the method name reflect its purpose.
Explanation:
When you write a component in Dagger 2, you group together modules containing #Provides methods. These #Provides methods can be thought of as "bindings" in that they associate an abstraction (e.g., a type) with a concrete way of resolving that type. With that in mind, the Foo foo() methods make the Component able to expose its binding for Foo to dependent components.
Example:
Let's say Foo is an application Singleton and we want to use it as a dependency for instances of DependsOnFoo but inside a component with narrower scope. If we write a naive #Provides method inside one of the modules of MyDependentComponent then we will get a new instance. Instead, we can write this:
#PerFragment
#Component(dependencies = {MyComponent.class }
modules = { MyDependentModule.class })
public class MyDependentComponent {
void inject(MyFragment frag);
}
And the module:
#Module
public class MyDepedentModule {
#Provides
#PerFragment
DependsOnFoo dependsOnFoo(Foo foo) {
return new DependsOnFoo(foo);
}
}
Assume also that the injection site for DependentComponent contains DependsOnFoo:
public class MyFragment extends Fragment {
#Inject DependsOnFoo dependsOnFoo
}
Note that MyDependentComponent only knows about the module MyDependentModule. Through that module, it knows it can provide DependsOnFoo using an instance of Foo, but it doesn't know how to provide Foo by itself. This happens despite MyDependentComponent being a dependent component of MyComponent. The Foo foo() method in MyComponent allows the dependent component MyDependentComponent to use MyComponent's binding for Foo to inject DependsOnFoo. Without this Foo foo() method, the compilation will fail.
Usage to resolve a binding
Let's say we would like to obtain instances of Foo without having to call inject(this). The Foo foo() method inside the component will allow this much the same way you can call getInstance() with Guice's Injector or Castle Windsor's Resolve. The illustration is as below:
public void fooConsumer() {
DaggerMyComponent component = DaggerMyComponent.builder.build();
Foo foo = component.foo();
}
Dagger is a way of wiring up graphs of objects and their dependencies. As an alternative to calling constructors directly, you obtain instances by requesting them from Dagger, or by supplying an object that you'd like to have injected with Dagger-created instances.
Let's make a coffee shop, that depends on a Provider<Coffee> and a CashRegister. Assume that you have those wired up within a module (maybe to LightRoastCoffee and DefaultCashRegister implementations).
public class CoffeeShop {
private final Provider<Coffee> coffeeProvider;
private final CashRegister register;
#Inject
public CoffeeShop(Provider<Coffee> coffeeProvider, CashRegister register) {
this.coffeeProvider = coffeeProvider;
this.register = register;
}
public void serve(Person person) {
cashRegister.takeMoneyFrom(person);
person.accept(coffeeProvider.get());
}
}
Now you need to get an instance of that CoffeeShop, but it only has a two-parameter constructor with its dependencies. So how do you do that? Simple: You tell Dagger to make a factory method available on the Component instance it generates.
#Component(modules = {/* ... */})
public interface CoffeeShopComponent {
CoffeeShop getCoffeeShop();
void inject(CoffeeService serviceToInject); // to be discussed below
}
When you call getCoffeeShop, Dagger creates the Provider<Coffee> to supply LightRoastCoffee, creates the DefaultCashRegister, supplies them to the Coffeeshop constructor, and returns you the result. Congratulations, you are the proud owner of a fully-wired-up coffeeshop.
Now, all of this is an alternative to void injection methods, which take an already-created instance and inject into it:
public class CoffeeService extends SomeFrameworkService {
#Inject CoffeeShop coffeeShop;
#Override public void initialize() {
// Before injection, your coffeeShop field is null.
DaggerCoffeeShopComponent.create().inject(this);
// Dagger inspects CoffeeService at compile time, so at runtime it can reach
// in and set the fields.
}
#Override public void alternativeInitialize() {
// The above is equivalent to this, though:
coffeeShop = DaggerCoffeeShopComponent.create().getCoffeeShop();
}
}
So, there you have it: Two different styles, both of which give you access to fully-injected graphs of objects without listing or caring about exactly which dependencies they need. You can prefer one or the other, or prefer factory methods for the top-level and members injection for Android or Service use-cases, or any other sort of mix and match.
(Note: Beyond their use as entry points into your object graph, no-arg getters known as provision methods are also useful for exposing bindings for component dependencies, as David Rawson describes in the other answer.)
I'm having a weird issue with the configureMetadataStore.
My model:
class SourceMaterial {
List<Job> Jobs {get; set;}
}
class Job {
public SourceMaterial SourceMaterial {get; set;}
}
class JobEditing : Job {}
class JobTranslation: Job {}
Module for configuring Job entities:
angular.module('cdt.request.model').factory('jobModel', ['breeze', 'dataService', 'entityService', modelFunc]);
function modelFunc(breeze, dataService, entityService) {
function Ctor() {
}
Ctor.extend = function (modelCtor) {
modelCtor.prototype = new Ctor();
modelCtor.prototype.constructor = modelCtor;
};
Ctor.prototype._configureMetadataStore = _configureMetadataStore;
return Ctor;
// constructor
function jobCtor() {
this.isScreenDeleted = null;
}
function _configureMetadataStore(entityName, metadataStore) {
metadataStore.registerEntityTypeCtor(entityName, jobCtor, jobInitializer);
}
function jobInitializer(job) { /* do stuff here */ }
}
Module for configuring JobEditing entities:
angular.module('cdt.request.model').factory(jobEditingModel, ['jobModel', modelFunc]);
function modelFunc(jobModel) {
function Ctor() {
this.configureMetadataStore = configureMetadataStore;
}
jobModel.extend(Ctor);
return Ctor;
function configureMetadataStore(metadataStore) {
return this._configureMetadataStore('JobEditing', metadataStore)
}
}
Module for configuring JobTranslation entities:
angular.module('cdt.request.model').factory(jobTranslationModel, ['jobModel', modelFunc]);
function modelFunc(jobModel) {
function Ctor() {
this.configureMetadataStore = configureMetadataStore;
}
jobModel.extend(Ctor);
return Ctor;
function configureMetadataStore(metadataStore) {
return this._configureMetadataStore('JobTranslation', metadataStore)
}
}
Then Models are configured like this :
JobEditingModel.configureMetadataStore(dataService.manager.metadataStore);
JobTranslationModel.configureMetadataStore(dataService.manager.metadataStore);
Now when I call createEntity for a JobEditing, the instance is created and at some point, breeze calls setNpValue and adds the newly created Job to the np SourceMaterial.
That's all fine, except that it is added twice !
It happens when rawAccessorFn(newValue); is called. In fact it is called twice.
And if I add a new type of job (hence I register a new type with the metadataStore), then the new Job is added three times to the np.
I can't see what I'm doing wrong. Can anyone help ?
EDIT
I've noticed that if I change:
metadataStore.registerEntityTypeCtor(entityName, jobCtor, jobInitializer);
to
metadataStore.registerEntityTypeCtor(entityName, null, jobInitializer);
Then everything works fine again ! So the problem is registering the same jobCtor function. Should that not be possible ?
Our Bad
Let's start with a Breeze bug, recently discovered, in the Breeze "backingStore" model library adapter.
There's a part of that adapter which is responsible for rewriting data properties of the entity constructor so that they become observable and self-validating and it kicks in when register a type with registerEntityTypeCtor.
It tries to keep track of which properties it has rewritten. The bug is that it records the fact of rewrite on the EntityType rather than on the constructor function. Consequently, every time you registered a new type, it failed to realize that it had already rewritten the properties of the base Job type and re-wrapped the property.
This was happening to you. Every derived type that you registered re-wrapped/re-wrote the properties of the base type (and of its base type, etc).
In your example, a base class Job property would be re-written 3 times and its inner logic executed 3 times if you registered three of its sub-types. And the problem disappeared when you stopped registering constructors of sub-types.
We're working on a revised Breeze "backingStore" model library adapter that won't have this problem and, coincidentally, will behave better in test scenarios (that's how we found the bug in the first place).
Your Bad?
Wow that's some hairy code you've got there. Why so complicated? In particular, why are you adding a one-time MetadataStore configuration to the prototypes of entity constructor functions?
I must be missing something. The code to register types is usually much smaller and simpler. I get that you want to put each type in its own file and have it self-register. The cost of that (as you've written it) is enormous bulk and complexity. Please reconsider your approach. Take a look at other Breeze samples, Zza-Node-Mongo for example.
Thanks for reporting the issue. Hang in there with us. A fix should be arriving soon ... I hope in the next release.
Let's say we have class:
public class WithDependencies
{
public WithDependencies(IAmDependencyOne first, IAmDependencyTwo second)
// ...
}
Now the question. How do you create objects of WithDependencies class in an application?
I know there are many ways.
new WithDependencies(new DependencyOne(), new DependencyTwo());
new WithDependencies(IoC.Resolve(IDependencyOne), IoC.Resolve(IDependencyTwo());
// register IDependencyOne, IDependencyTwo implementations at app start
IoC.Resolve(WithDependencies);
// register IDependencyOne, IDependencyTwo implementations at app start
// isolate ourselves from concrete IoC Container
MyCustomWithDependenciesFactory.Create();
and so on...
What do you think is the way to do it?
Edit:
Because I don't get answers or I don't understand them I'll try to ask again. Let's say that on some event (button, timer, whatever) I need new object WithDependencies(). How do I create it? Assume IoC container is already configured.
It depends on the context, so it's impossible to provide a single answer. Conceptually you'd be doing something like this from the Composition Root:
var wd = new WithDependencies(new DependencyOne(), new DependencyTwo());
However, even in the absence of a DI Container, the above code isn't always unambiguously the correct answer. In some cases, you might want to share the same dependency among several consumers, like this:
var dep1 = new DependencyOne();
var wd = new WithDependencies(dep1, new DependencyTwo());
var another = AnotherWithDependencies(dep1, new DependencyThree());
In other cases, you might not want to share dependencies, in which case the first option is more correct.
This is just a small glimpse of an entire dimension of DI concerned with Lifetime Management. Many DI Containers can take care of that for you, which is one excellent argument to prefer a DI Container over Poor Man's DI.
Once you start using a DI Container, you should follow the Register Resolve Release pattern when resolving types, letting Auto-wiring take care of the actual composition:
var wd = container.Resolve<WithDependencies>();
The above example assumes that the container is already correctly configured.
If you need to create a dependency which has its own dependencies, you can either A) do it yourself, or B) ask something else to do it for you. Option A negates the benefits of dependency injection (decoupling, etc.), so I would say option B is a better starting point. Now, we have chosen to use the factory pattern, no matter whether it takes the form of a service locator (i.e. IoC.Resolve), a static factory, or an instance factory. The point is that we have delegated that responsibility to an external authority.
There are a number of trade-offs required for static accessors. (I went over them in another answer, so I won't repeat them here.) In order to avoid introducing a dependency on the infrastructure or the container, a solid option is to accept a factory for creating WithDependencies when we need an instance somewhere else:
public class NeedsWithDependencies
{
private readonly IWithDependenciesFactory _withDependenciesFactory;
public NeedsWithDependencies(IWithDependenciesFactory withDependenciesFactory)
{
_withDependenciesFactory = withDependenciesFactory;
}
public void Foo()
{
var withDependencies = _withDependenciesFactory.Create();
...Use the instance...
}
}
Next, we can create a container-specific implementation of the factory:
public class WithDependenciesFactory : IWithDependenciesFactory
{
private readonly IContainer _container;
public WithDependenciesFactory(IContainer container)
{
_container = container
}
public WithDependencies Create()
{
return _container.Resolve<WithDependencies>();
}
}
Now NeedsWithDependencies is completely isolated from any knowledge of how WithDependencies gets created; it also exposes all its dependencies in its constructor, instead of hiding dependencies on static accessors, making it easy to reuse and test.
Defining all those factories can get a little cumbersome, though. I like Autofac's factory relationship type, which will detect parameters of the form Func<TDependency> and automatically inject a function which serves the same purpose as the hand-coded factory above:
public class NeedsWithDependencies
{
private readonly Func<WithDependencies> _withDependenciesFactory;
public NeedsWithDependencies(Func<WithDependencies> withDependenciesFactory)
{
_withDependenciesFactory = withDependenciesFactory;
}
public void Foo()
{
var withDependencies = _withDependenciesFactory();
...Use the instance...
}
}
It also works great with runtime parameters:
public class NeedsWithDependencies
{
private readonly Func<int, WithDependencies> _withDependenciesFactory;
public NeedsWithDependencies(Func<int, WithDependencies> withDependenciesFactory)
{
_withDependenciesFactory = withDependenciesFactory;
}
public void Foo(int x)
{
var withDependencies = _withDependenciesFactory(x);
...Use the instance...
}
}
Sometimes I try to get rid of factories or at least not depend directly on them, so Dependency Injection (without factories) is useful of course.
Therefore I use Google Juice, cause its a small little framework using Java Annotations and you can quickly change your injections / dependencies. Just take a look at it:
http://code.google.com/p/google-guice/
i'm looking for a larger example of dependency injection and how it can be implemented. If class A depends on class B and passes a reference of class C to B's constructor, must not class A also take a reference to class C in it's constructor? This means that the main method in the application should create all classes really, which sounds wierd?
I understand that using DI frameworks we can have it in XML files somehow, but that sounds like it could be hard to quickly see what type that really is instanciated? Especially if it a very large application.
You are correct and each DI framework has a different way of managing it.
Some use attributes on the properties etc to denote dependency and then "automagically" supply an instance of the correct type, while others (say castle windsor for .net) allow xml configuration, fluent or other methods for "wiring up" the dependency graph.
Also no, class A takes a built reference to an instance of B which was built using an instance of C. A needs to know nothing about C unless exposed via B.
public class C { }
public class B { public B(C c) { ... }}
public class A { public A(B b) { ... }}
// manual wireup
C c = new C();
B b = new B(c);
A a = new A(b);
// DI framework
InversionOfControlContainer container = new InversionOfControlContainer(... some configuration);
A a = container.ResolveInstanceOf<A>();
// container dynamically resolves the dependencies of A.
// it doesnt matter if the dependency chain on A is 100 classes long or 3.
// you need an instance of A and it will give you one.
Hope that helps.
to answer your question about classes A,B,and C, A only needs a reference to B.
Most DI frameworks do not require you to use XML for configuration. In fact, many people prefer not to use it. You can explicitly set things up in code, or use some kind of conventions or attributes for the container to infer what objects should fulfil dependencies.
Most DI frameworks have a facility for "lazy loading" to avoid the creation of every single class up front. Or you could inject your own "factory or builder" objects to create things closer to the time when they will be used
You've not said what language you are using. My example below is in C# using the Unity container. (obviously normally you would use interfaces rather than concrete types):
container = new UnityContainer();
container.RegisterType<C>();
container.RegisterType<B>();
A a = container.Resolve<A>();
here's a few examples from the PHP Language, hope this helps you understand
class Users
{
var $Database;
public function __construct(Database $DB)
{
$this->Database = $DB;
}
}
$Database = Database::getInstance();
$Users = new Users($Database);
From this example the new keyword is used in the method getInstance(), you can also do
$Users = new Users(Database::getInstance());
Or another way to tackle this is
class Users
{
/*Dependencies*/
private $database,$fileWriter;
public function addDependency($Name,$Object)
{
$this->$Name = $Object;
return $this;
}
}
$Users = new Users();
$Users->addDependency('database',new Database)->addDependency('fileWriter',new FileWriter);
Update:
to be honest, I never use Dependency Injection as all its doing is passing objects into classes to create a local scope.
I tend to create a global entity, and store objects within that so there only ever stored in 1 variable.
Let me show you a small example:
abstract class Registry
{
static $objects = array();
public function get($name)
{
return isset(self::$objects[$name]) ? self::$objects[$name] : null;
}
public function set($name,$object)
{
self::$objects[$name] = $object;
}
}
Ok the beauty of this type of class is
its very lightweight
it has a global scope
you can store anything such as resources
When your system loads up and your including and initializing all your objects you can just store them in here like so:
Registry::add('Database',new Database());
Registry::add('Reporter',new Reporter());
Where ever you are within your runtime you can just use this like a global variable:
class Users
{
public function getUserById($id)
{
$query = "SELECT * FROM users WHERE user_id = :id";
$resource = Registry::get("Database")->prepare($query);
$resource->bindParam(':id',$id,PDO::PARAM_INT);
if($resource->execute())
{
//etc
}else
{
Registry::get('Reporter')->Add("Unable to select getUserById");
}
}
}
i see this way of object passing is much cleaner
If anybody is still looking for a good example which shows DI without IoC Containers (poor man's DI) and also with IoC Container (Unity in this example) and registering the types in code and also in XML you can check this out: https://dannyvanderkraan.wordpress.com/2015/06/15/real-world-example-of-dependeny-injection/
We are trying to figure out how to setup Dependency Injection for situations where service classes can have different dependencies based on how they are used. In our specific case, we have a web app where 95% of the time the connection string is the same for the entire Request (this is a web application), but sometimes it can change.
For example, we might have 2 classes with the following dependencies (simplified version - service actually has 4 dependencies):
public LoginService (IUserRepository userRep)
{
}
public UserRepository (IContext dbContext)
{
}
In our IoC container, most of our dependencies are auto-wired except the Context for which I have something like this (not actual code, it's from memory ... this is StructureMap):
x.ForRequestedType().Use()
.WithCtorArg("connectionString").EqualTo(Session["ConnString"]);
For 95% of our web application, this works perfectly. However, we have some admin-type functions that must operate across thousands of databases (one per client). Basically, we'd want to do this:
public CreateUserList(IList<string> connStrings)
{
foreach (connString in connStrings)
{
//first create dependency graph using new connection string
????
//then call service method on new database
_loginService.GetReportDataForAllUsers();
}
}
My question is: How do we create that new dependency graph for each time through the loop, while maintaining something that can easily be tested?
To defer the creation of an object until runtime, you can use a factory:
public interface ILoginServiceFactory
{
ILoginService CreateLoginService(string connectionString);
}
Usage:
public void CreateUserList(IList<string> connStrings)
{
foreach(connString in connStrings)
{
var loginService = _loginServiceFactory.CreateLoginService(connString);
loginService.GetReportDataForAllUsers();
}
}
Within the loop, do:
container.With("connectionString").EqualTo(connString).GetInstance<ILoginService>()
where "connectionString" is the name of a string constructor parameter on the concrete implementation of ILoginService.
So most UserRepository methods use a single connection string obtained from session, but several methods need to operate against a list of connection strings?
You can solve this problem by promoting the connection string dependency from IContext to the repository and adding two additional dependencies - a context factory and a list of all the possible connections strings the repository might need to do its work:
public UserRepository(IContextFactory contextFactory,
string defaultConnectionString,
List<string> allConnectionStrings)
Then each of its methods can build as many IContext instances as they need:
// In UserRepository
public CreateUserList() {
foreach (string connString in allConnectionStrings) {
IContext context = contextFactory.CreateInstance(connString);
// Build the rest of the dependency graph, etc.
_loginService.GetReportDataForAllUsers();
}
}
public LoginUser() {
IContext context = contextFactory.CreateInstance(defaultConnectionString);
// Build the rest of the dependency graph, etc.
}
We ended up just creating a concrete context and injecting that, then changing creating a wrapper class that changed the context's connection string. Seemed to work fine.