Dependency Injection: How to construct a class that depends on runtime parameters? - dependency-injection

I want to introduce DI to our application.
In our application, we have some generic parameters that are passed through the entire
application, mostly via constructor parameters.
For example the parameter region limits all actions to a geographic region. This parameter is gathered from user input at runtime and thereby not known at the composition root.
How should I create classes that are always limited to work on one region?
I know that I could use the factory pattern. In this case I would need to pass the DIC into the factory, which is (as far as I know) an anti-pattern.

The factory pattern is certainly NOT an anti-pattern when working with DI, even though you will see the number of factories decrease when you apply DI correctly.
Still in your situation a factory might not be the best approach. Typically you should prevent letting the object graph depend on runtime data and you should separate the need for that request specific data from the composition of your services.
In your case it would probably be easy to have some sort of IRegionContext or IRegionManager abstraction that allows to to get the region for the current request. This IRegionContext itself is a service, but contains a method that can be called by the application after the object graph is contructed:
public interface IRegionContext
{
Region CurrentRegion { get; }
}
Application types can depend on the IRegionContext and in the composition root of your web application you can have a special AspNetRegionContext implementation that allows retrieving the region based on the current request.

Related

Object lifecycle management and IoC containers

I'm updating a game from single player to multiplayer. In this case the game was originally written with most classes being single instanced. e.g. there was a single Player object, a single GameState object, etc. That is, each of these objects lived as long as the application.
Now that more than one player can play at once I obviously need to support creating more than one Player object, GameState object, etc. Over the course of working on this I have come to realize that most objects have one of three lifespans:
App's lifespan, e.g. a Conductor to handle navigation
Player's lifespan, e.g. the SettingsViewModel for the current player
Game's lifespan, e.g. the GameState for the current game
I'm curious how others deal with the creation of these different objects using an IoC container. I want to avoid creating factory classes for each class with a player or game lifespan.
Here is an example of IOC that may help. The project is called IOC-with-Ninject. It uses Ninject plus an IOC container class to manage all object life spans. You will need to do a little research on Ninject to customize it to your specific needs, but this is your IOC container solution (IMHO) if you are using .NET and will help you organize your code base. This is a personal choice, but I swear by it. If you are not using .NET it will still give you an easy pattern to follow. Cheers.
Many IoC containers have custom life-cycle scopes which you can manage as your wish. For example in Ninject you can define your custom life cycle scope as follows:
kernel.Bind<IService>().To<Service>().InScope((c, o) => yourCustomeScope);
As long as the yourCustomeScope variable has not changed, one single instance of the Service object is returned each time the kernel receives a request for IService. As soon as the yourCustomeScope variable changes, a new instance of Service will be created on the next request for IService. yourCustomeScope can be the current player instance, the game object or anything that you want to change the lifetime of the Service object, based on its reference change.
However, the objects that you just mentioned are more likely to be entities rather than services for which I don't think injection is a good idea.
From my experience the factories approach works the best.
Controlling lifespan of instance is clunky for support and requires efforts, knowledge of all of the classes lifespan requirements and dependencies, time for configuration and management of the configuration. In same time the use of factories is natural and code specific.
Factories (implementation) creation might be avoided by using proxy factories . You can also have factories returning generic arguments to further decrease the needs of factories (interfaces) creation.
If still too many factories are required I suggest reviewing the code flow.
I think this is in part a rehash of some of the comments of the previous answers but I have tried to exemplify expand a little on some of the reasoning.
Once you get into the domain of managing injected objects lifespan, you probably should be creating factories for these objects.
The underlying problem is that the composition root is not aware of what the environmental context of the call will be that needs to create the object.
I think I should take a step back and explain at this point.
Received wisdom on dependancy injection is to have a composition root some where near the entry point of the code. There are many good reasons for this that are not difficult to find on the web so I won't go into that here.
The composition root is where you map your interfaces (usually, but possibly objects) to their implmentations. You can pass in information that is available at this point to the constructor. So you can pass in a reference to an object whose lifetime is current at the time of execution of the composition root.
However, if the lifetime of the composition root does not overlap with the life time of the object you want to create you have to defer the execution of the constructor until the object needs to be created. This is why you need to have a factory. You can pass a factory method in to your mapping at this point and thus pass in the information needed to generate the object, but allow the creation to happen at the time it is required not when the composition root is executed.
You do not need a factory class to do this factory methods are fine, moreover the factory method can be inlined and so the code overhead is not much more than if we were creating the objects in the composition route.
If we have a project with 2 services where the first service is dependant on the first and we only want the lifetime of the second service to start when we create the first service we might have something like the following. (I am using ninject to give a code example, but I expect that other IOC containers work similarly in this respect.)
`
public class Service1:IService
{
private Func<IService>serviceFactoryMethod _Service2Factory;
public Service1(Func<IService>service2FactoryMethod)
{
_Service2Factory=service2FactoryMethod;
}
public void DoSomethingUsingService2()
{
var service2=_Service2Factory();
service2.DoSomething();
}
}
public class MainClass
{
public void CompositionRoot()
{
var kernel= new StandardKernel();
kernel.Bind.ToMethod(m=>
{
return new Service1(m.Kernel.Get<IService2>());
}
}
}
`
This example does not address how you would manage the lifetime of the App, players and games lifespans, but hopefully it gives sufficient clues as to how to remove lifetime issues related to dependancy injection.
Side note: that using Ninject you would be able to change the scope of Service2 in order to manage its lifetime to go beoynd the lifetime of Service1. For example, if you knew each instance of a game were to happen on its own thread (OK, this maybe somewhat unlikely), you might use InThreadScope for the game.

DI Container and custom-scoped state in legacy system

I believe I understand the basic concepts of DI / IoC containers having written a couple of applications using them and reading a lot of stack overflow answers as well as Mark Seeman's book. There are still some cases that I have trouble with, especially when it comes to integrating DI container to a large existing architecture where DI principle hasn't been really used (think big ball of mud).
I know the ideal scenario is to have a single composition root / object graph per operation but in a legacy system this might not be possible without major refactoring (only the new and some select refactored old parts of the code could have dependencies injected through constructor and the rest of the system using the container as a service locator to interact with the new parts). This effectively means that a stack trace deep within an operation might include several object graphs with calls being made back and forth between new subsystems (single object graph until exiting into an old segment) and traditional subsystems (service locator call at some point to code under DI container).
With the (potentially faulty, I might be overthinking this or be completely wrong in assuming this kind of hybrid architecture is a good idea) assumptions out of the way, here's the actual problem:
Let's say we have a thread pool executing scheduled jobs of various types defined in database (or any external place). Each separate type of scheduled job is implemented as a class inheriting a common base class. When the job is started, it gets fed the information about which targets it should write its log messages to and the configuration it should use. The configuration could probably be handled by just passing the values as method parameters to whatever class needs them but if the job implementation gets larger than say 10-20 classes, it doesn't seem very handy.
Logging is the larger problem. Subsystems the job calls probably also need to write things to the log and usually in examples this is done by just requesting instance of ILog in the constructor. But how does that work in this case when we don't know the details / implementation until runtime? Since:
Due to (non DI container controlled) legacy system segments in the call chain (-> there potentially being multiple separate object graphs), child container cannot be used to inject the custom logger for specific sub-scope
Manual property injection would basically require the complete call chain (including all legacy subsystems) to be updated
A simplified example to help better perceive the problem:
Class JobXImplementation : JobBase {
// through constructor injection
ILoggerFactory _loggerFactory;
JobXExtraLogic _jobXExtras;
public void Run(JobConfig configurationFromDatabase)
{
ILog log = _loggerFactory.Create(configurationFromDatabase.targets);
// if there were no legacy parts in the call chain, I would register log as instance to a child container and Resolve next part of the call chain and everyone requesting ILog would get the correct logging targets
// do stuff
_jobXExtras.DoStuff(configurationFromDatabase, log);
}
}
Class JobXExtraLogic {
public void DoStuff(JobConfig configurationFromDatabase, ILog log) {
// call to legacy sub-system
var old = new OldClass(log, configurationFromDatabase.SomeRandomSetting);
old.DoOldStuff();
}
}
Class OldClass {
public void DoOldStuff() {
// moar stuff
var old = new AnotherOldClass();
old.DoMoreOldStuff();
}
}
Class AnotherOldClass {
public void DoMoreOldStuff() {
// call to a new subsystem
var newSystemEntryPoint = DIContainerAsServiceLocator.Resolve<INewSubsystemEntryPoint>();
newSystemEntryPoint.DoNewStuff();
}
}
Class NewSubsystemEntryPoint : INewSubsystemEntryPoint {
public void DoNewStuff() {
// want to log something...
}
}
I'm sure you get the picture by this point.
Instantiating old classes through DI is a non-starter since many of them use (often multiple) constructors to inject values instead of dependencies and would have to be refactored one by one. The caller basically implicitly controls the lifetime of the object and this is assumed in the implementations (the way they handle internal object state).
What are my options? What other kinds of problems could you possibly see in a situation like this? Is trying to only use constructor injection in this kind of environment even feasible?
Great question. In general, I would say that an IoC container loses a lot of its effectiveness when only a portion of the code is DI-friendly.
Books like Working Effectively with Legacy Code and Dependency Injection in .NET both talk about ways to tease apart objects and classes to make DI viable in code bases like the one you described.
Getting the system under test would be my first priority. I'd pick a functional area to start with, one with few dependencies on other functional areas.
I don't see a problem with moving beyond constructor injection to setter injection where it makes sense, and it might offer you a stepping stone to constructor injection. Adding a property is usually less invasive than changing an object's constructor.

Is it considered bad design to pass a repository interface as an argument to a method on a domain class?

Our domain model is very anemic right now. Our entities are mostly empty shells, almost purely designed for holding values and navigating to collections.
We are using EF 4.1 code-first ORM, and the design so far has been to shield our novice developers against the dreaded "LINQ to Entities cannot translate blablabla to a store expression" exception when querying against the context during early iterations.
We have various aggregate root repository interfaces over EF. However some blocks of code in the impls seems like they should be the domain's responsibility. As long as the repository interface is declared in the domain, and the impl is in the infrastructure (dependency injected), is it considered bad design to pass a repository interface as an argument to a method on an entity (or other domain) class?
For example, would this be bad?
public class EntityAbc {
public void SaveTo(IEntityAbcRepository repos) {...}
public void DeleteFrom(IEntityAbcRepository repos) {...}
}
What if a particular entity needed access to other aggregate root repositories? Would this be ok or not, and why?
public void Save() {
var abcRepos = DependencyInjector.Current.GetService<IEntityAbcRepository>();
var xyzRepos = DependencyInjector.Current.GetService<IEntityXyzRepository>();
// work with repositories
}
Update 1
I did not mention moving code to an application layer because I consider some of the code that uses IEntityAbcRepository to involve business rule enforcement. The repository impl should be as vanilla as possible, right? Its main responsibility should just be a simple abstraction over the ORM, allowing you to find / add / update / delete entities. Wrong?
Also, this question applies to methods on other non-entity domain classes -- factories, services, whatever pattern may be appropriate. Point being, I'm asking the question about any method on a domain class, not just an entity class. #Eranga, this is one place where you can use constructor injection because factories & services are not part of the ORM.
The application layer could then coordinate flow by injecting a repository impl into its constructor, and passing it as an argument to a domain service or factory. Is this bad practice?
Update 2
Adding another clarification here. What if the domain only needs access to the IEntityAbcRepository in order to execute its Find() method(s)? In the example above, the SaveTo and DeleteFrom methods would not invoke any add / update / delete methods on the repository interface.
So far we've combined the find / add / update / delete methods on a single aggregate root repository interface for simplicity. But I suppose there's nothing stopping us from separating them out into 2 interfaces, like so:
IEntityAbcReadRepository <-- defines all find method signatures
IEntityAbcWriteRepository <-- defines all add / update / delete method sigs
In this case, would it be bad practice to pass IEntityAbcReadRepository as a parameter to a domain method?
Your first approach is better compared to the second approach which uses "Service Locator" pattern. Dependencies are more obvious in the first approach.
Here are some links that explains why "Service Locator" is a bad choice
Is it bad to use servicelocation instead of constructor injection
...
Singleton Vs ServiceLocator
Say no to ServiceLocator
Both of these solutions stem from the fact that EF does not allow you to use constructor injection. However you can use property injection as explained in this answer. But that does not guarantee that mandatory dependencies are present.
So your first approach is the better solution.
Short answer: Yes!
Long answer:
Consider creating an AbcService in your application service layer. This service layer sits between your domain and your infrastructure. You can inject as many repositories into AbcService as you want. Then let the service handle SaveTo and DeleteFrom.
SaveTo and DeleteFrom, unless you are saving to and deleting from another entity, i.e. no data access is involved, are methods that sound like they shouldn't be on a domain entity, IMO.
Having persistence logic in your domain entities is IMO bad design in the first place. Good separation of concerns should mean that domain/business logic is separated from persistence logic, so your domain classes should be persistence ignorant.
Previous Entity Framwork versions might not have allowed such a separation but I think most recent versions solved that problem. I'm not that familiar with EF though, so I might be wrong.
With that said, where can you put methods such as Save() and Delete() ?
If you want to add to/remove your entity from its repository, Repository.Add() and Repository.Remove() are good choices. A repository basically serves as an illusion of an in-memory collection of your entities, so it makes sense for it to behave just like a collection or a list with the appropriate methods.
If you want to persist changes made to an existing entity, there are other ways to do that. You could have a Repository.Save() method but some consider it bad practice. Oftentimes the changes are part of a higher level operation handled in a transaction-like context such as a Unit of Work, in that case you can let the operation persist all the objects in its scope when it finishes. For instance, if you use an Open Session in View approach for your web application, changes are automatically persisted when the request ends.
Or you can rely on an ad-hoc call of your ORM's Save() method for your particular entity which hopefully shouldn't be grafted onto the entity code itself (with NHibernate, for instance, it's available at runtime on the proxied entity).
[Update]
Putting that in perspective with your subsequent questions (though I'm not sure I understand all of them well) :
I see no value in splitting your repository into a ReadRepository and a WriteRepository. In DDD, a repository's responsibility is clearly to provide a collection to query from as well as add to or remove from. It's still quite cohesive that way.
It's not an entity's responsibility to fiddle with its own persistence, so it shouldn't be aware of its own repository for that precise purpose. Otherwise, it's pretty rare that an entity rightfully needs to have knowledge of its own repository (usually it means that the entity has a relationship to another entity of the same type, like parent/child, and you want to get the other entity from the repository)
However, entities and other domain objects obviously do need to obtain references to other entities at times. In that case, try to get these references through traversal of other objects within the boundary of your aggregate first before looking for a repository. If you absolutely need a repository to get the object you want, it's a good idea to inject the repository through any flavour of injection you like. As Eranga pointed out, service locator might turn out to be a sub-par dependency injection ersatz though.
Last thing, the kind of injection you mentioned - SaveTo(IEntityAbcRepository repos) - is peculiar because it is neither constructor nor setter injection, but rather an ephemeral injection lasting just the time of a method. It implies that whoever calls your method must know what repository to pass at that precise moment, which is not obvious. It might be useful, but I'd say it's not the form of injection you would typically mainly use.

What is the best strategy for Dependency Injection of User Input?

I've used a fair amount of dependency injection, but I'd like to get input on how to handle information from the user at runtime.
I have a class that connects to a com port. I allow the user to select the com port number. Right now, I have that com port parameter as a constructor argument. The reasoning being that the class cannot function without that information, and it's implementation specific (a mock version of this class wouldn't need a com port).
The alternative is to have a "Start" method that takes in the com port, or have a property that sets the com port. This makes it very compatible with an IoC container, but it doesn't necessarily make sense from the perspective of the class.
It seems like the logical route conflicts with the dependency injection design, but it's because my UI is getting information for a specific type of class.
Other alternatives would include using an IoC container that lets me pass in additional constructor parameters, or just constructing the classes I need at the top level without using dependency injection.
Is there a generally accepted standard pattern for this type of problem?
There are two routes you can take, depending on your needs.
1. Wire the UI directly to your concrete classes
This is the simplest option, but many times perfectly acceptable. While you may have a Domain Model with lots of interfaces and use of DI, the UI constitutes the Composition Root of the object graphs, and you could simply wire up your concrete class here, including your required port number parameter.
The upside is that this approach is simple and easy to understand and implement.
The downside is that you get less flexibility. You will not be able to arbitrarily replace one implementation with another (but then again, you may not need that flexibility).
Even with the UI locked to a concrete implementation, this doesn't mean that the Domain Model itself wouldn't be reusable in other applications.
2. Add an Abstract Factory
The other option is to add another layer of indirection. Instead of having your UI create the class directly, it could use an Abstract Factory to create the instance.
The factory's Create method could take the port number as an input, so this abstraction belongs best in a UI sub-layer.
public abstract class MyFactory
{
public abstract IMyInterface Create(int portNumber);
}
You could then have your DI container wire up an implementation of this factory that uses the port number and passes it as a constructor argument to your real implementation. Other factory implementations may simply ignore the parameter.
The advantage of this approach is that you don't pollute your API (or your concrete implementations), and you still have the flexibility that programming to interfaces give you.
The disadvantage is that it adds yet another layer of indirection.
Most IoC containers have some form of Constructor Injection that would allow your IoC container to pass a mocked COM port into your class for unit testing. That seems like the most clean solution.
I would avoid adding a "Start" method, etc. Its much better practice to (when possible) always have your classes in a valid state, and switching to a parameterless constructor with a start method leaves your class invalid between those calls. Doing this to enable testing is just making your class more difficult in order to test (which should make it nicer).

Inversion of control domain objects construction problem

As I understand IoC-container is helpful in creation of application-level objects like services and factories. But domain-level objects should be created manually.
Spring's manual tells us: "Typically one does not configure fine-grained domain objects in the container, because it is usually the responsibility of DAOs and business logic to create/load domain objects."
Well. But what if my domain "fine-grained" object depends on some application-level object.
For example I have an UserViewer(User user, UserConstants constants) class.
There user is domain object which cannot be injected, but UserViewer also needs UserConstants which is high-level object injected by IoC-container.
I want to inject UserConstants from the IoC-container, but I also need a transient runtime parameter User here.
What is wrong with the design?
Thanks in advance!
UPDATE
It seems I was not precise enough with my question. What I really need is an example how to do this:
create instance of class UserViewer(User user, UserService service), where user is passed as the parameter and service is injected from IoC.
If I inject UserViewer viewer then how do I pass user to it?
If I create UserViewer viewer manually then how do I pass service to it?
there's nothing wrong with this design. you use Factories for that, which have one leg in the domain, one leg in infrastructure.
You can either write them manually, or have the container do that for you, by things like TypedFactoryFacility in Windsor.
Also when your domain objects come from persistence layer you can plug your container there to inject the services they require (NHibernate can do that).
But what if my domain "fine-grained" object depends on some application-level object?
It is precisely this that is considered bad-practice. I would say the problems could be:
There are tons of these objects, so there can be performance and memory issues.
The POJO style is that they can be used in all environments (persisted in the database, processed in business algorithms and rules, read and set in view technologies, serialized and send over the network). Injecting application-level objects in them could cause the following problems:
In your architecture, you probably have the rule that some (most) application-level objects are usable in some layers, not in others. Because all layers have access to the pojos, the rule would be violated transitively.
When serialized and rebuild in another JVM, what would be the meaning of your application-level objects. They are useless, they must be changed for the local equivalents...
Typically, the pojos that constitute your domain are self-contained. They can have access to other pojos (and many enums), that's all.
In addition to the data, they have methods that implement the details of the business rules or algorithms (remember the OO idea of grouping data and code that work on it ;-) ):
This is especially good when they have inheritance, as this allow to customize a business rule for some pojo by providing a different implementation (differing case without if or switch: remember OO? ;-) ).
Any code that requires access to application-level objects (like accessing the database) is taken out, for example to a Service or Manager. But that code stays high level, thus readable and simple, because the pojos themselves take care of the low level details (and the special cases).
After the fact, you often find out that the pojo methods get reused a lot, and composed in different ways by the Services or Managers. That's a big win on reducing duplication, the methods names provide much needed "meaning", and provide an easier access to developers that are new to a module.
For your update:
create instance of class UserViewer(User user, UserService service), where user is passed as the parameter and service is injected from IoC.
If I inject UserViewer viewer then how do I pass user to it?
If I create UserViewer viewer manually then how do I pass service to it?
In that case, you need a factory method (possibly on a Factory or Locator of yours). It could look at follow, separating the two parts:
public UserViewer createUserViewer(User user) {
UserViewer viewer = instantiateBean(UserViewer.class);
viewer.setUser(user);
return viewer;
}
private <E> E instantiateBean(Class<E> clazz) {
// call the IoC container to create and inject a bean
}

Resources