Multi-level DI refactoring - c#

I don't know if this actually qualifies as DI, since I'm not talking about injecting a concrete implementation of an abstract dependency. I'm just talking about injecting stuff that's needed period.
In my game engine, I want to clean up the part that handles the state of the game (menu, stage select, in-game, cutscenes, etc). All of these things implement a common interface. But one of them, in-game, is also referenced specifically as the current level being played.
There are right now 43 references in my project to the current level, as accessed through the game, a singleton. For example, Game.CurrentGame.CurrentMap.Something. The references are in screens, entities, behavior components, even in the main form (for debugging tools).
I want to get rid of this reference by injecting everything that's needed. But the CurrentMap itself isn't the desired dependency - other things are being accessed below it. So my initial plan is to go into each place, find the thing that's actually being used, and inject it by adding a parameter to that class constructor. This introduces another dependency one level up, so I repeat the process until everything is finished. But the problem with this is it will introduce a lot more constructor parameters, including in places that aren't using the dependency directly. A lot of classes will wind up accepting a dependency just so they can pass it on to another object below them.
What would be a cleaner alternative to this?

You are talking about a scenario where the dependencies must make their way down through a few layers of objects to get where they are really needed. This does not need to happen.
If an object creates dependencies itself you end up with this problem. If objects are given the dependencies it needs by a factory or DI container (which is just a fancy factory) then you will not have this problem. So to avoid this problem, you need to decide if each class is concerned with game logic or creating classes.
Let's say you have object a, which calls object b, which calls object c and object c needs the current level and object b does not.
The wrong way to do it is to call new C(level); from within b. As you have pointed out, b does not need to know about the level so it seems things are getting worse not better. You have not gone far enough with the dependency injection. Instead of creating c within b, just ask for c in the constructor of b. Now class b only knows about c and knows nothing about level.
Misko has explained this better than I can here http://misko.hevery.com/2009/03/30/collaborator-vs-the-factory/
Code in the factory looks like this:
Level level = new Level();
C c = new C( level );
B b = new B( c );
A a = new A( b );
The class B only knows about it's direct collaborators (c) and has no dependency on Level. Because we are creating things in the factory, it is not necessary to pass the leaves of the object graph down through the object graph.
If class B had the responsibility for creating c then it needs to know all about how to make an instance of class c. This is wrong.

Look at using a DI Framework, like Castle Windsor, Structuremap or Unity (there are plenty of others that are perfectly solid as well).
The problem you are describing is not the only problem that these frameworks solve, but it's a big part of the type of friction that they almost completely eliminate.
The fact that the dependencies are concrete implementations and not higher level abstractions is irrelevant. See this question (asked by yours truly):
IOC/DI: Is Registering a Concrete Type a Code Smell?

Usually I inject a service that keeps track of the current state:
public interface IGameStateTracker
{
Game CurrentGame {get;}
GameMap CurrentMap {get;}
}
You should only have to inject this service in constructors of classes that will need it directly. I'm afraid I don't fully understand why you're finding that you need to inject things into classes that don't directly need it: this may be a sign that you're not using proper DI patterns. Could you provide some code samples to show an example of this problem?
I second Phil Sandler's point about using a DI framework. It will make life much easier. But it won't make up for using incorrect DI patterns in the first place.

Related

Factory pattern and my incapacity. Help me see the light

Let's keep it simple...
class Client
abstract class AbstractBusinessObject
class BusinessObject
class BusinessObjectFactory
Okay, so your Client needs to perform some operations on AbstractBusinessObject . Obviously somewhere one BusinessObject instance needs to be created. Why not in the client? What's the harm?
Let's assume you convinced me to create new BusinessObjects in my BusinessObjectFactory. Great. Now the factory has to do the heavy lifting. Let's assume my factory has a Create(DataRow row) method because my BusinessObject needs the DataRow to extract useful information from it.
My BusinessObject's properties are {get; private set;}. Therefore I cannot assign any property values in my factory. Probably I shouldn't anyway.
This however means I have to pass along the DataRow entirely. So basically the factory just passes along my parameter. What's the use of the factory here?
Ok so I might have different implementation of BusinessObject - each of them having different constructors. I guess it makes sense for the factory to know how to construct any specific BusinessObject then. But then again I need a specific factory to get a specific BusinessObject. At least all examples I saw suggest just that. ConcreteFactoryB creates ConcreteProductB (ConcreteFactoryA creates ConcreteProductA) How does the client know how to construct the factory? Or even which one to create?
Ah the factory is injected... composition root. Right. But I could have injected the BusinessObject directly just as well.
The example over at DoFactory made it a little bit more clear I think. Is it all about making sure the Lion doesn't eat Bisons? And the Wolf doesn't feed on Wildebeests? If that's all the factory tries to assure I don't need one if I just want to create a single object, right?
So does a factory like this one here make any sense? Does a factory ever make sense if I only have one Create() method which only makes one type of classes?
Really, I read a lot about it.
Every example looks like the other. I'm missing the point :( Can anyone provide a crystal clear real world example?
https://stackoverflow.com/a/2280289/1407618
Been there, done that...
You are a Person using an AbstractComputer. You do not care about the make of the computer, as long as it has all the basic stuff an AbstractComputer have. Now, in order to use a computer, would you Create() one yourself or would you get it from a ComputerStore or ComputerProvider? Those are going to give you the computer that best fits your needs (i.e. your budget, skills, screen size). They got their AbstractComputer shipped from a ComputerFactory that knows how to Create them best.
As for the properties of your AbstractComputer, some make it possible to swap the Storage and some don't. It really depends on your context. But for your factory to put them inside the computer, they needed an entry point (constructor) if they are not swappable after it is constructed.
The important point is that it is not the responsibility of the AbstractComputer to know how to constructs himself given the pieces. Nor it is the responsibility of the Consumer to know which make of computer it needs (they sometimes can, if they have enough knowledge and that their needs will never ever change).
(It looks like you accept the idea that dependency injection is (often) useful, so I'll base my answer on that assumption.)
If an instance of A depends on an instance of B, and you already have the B instance, then you should indeed inject it into the A instance without using a factory. However, factories are useful in these situations:
Lazy loading: You don't have the B at the time you create the A, so A needs to create its own B (without knowing exactly what type B is, and possibly without knowing (all) of B's dependencies).
Optional loading: In some situations, loading B might not even be necessary, and whether it is necessary or not must be determined by A.
Multiple instances: A might need to create multiple instances of B whenever it wants to do so.
As usual, no pattern is a silver bullet, so there are many situations in which factories or dependency injection are overkill. Your questioning of the usefulness of factories is good, and will probably lead to you only using the pattern when it's actually beneficial.

does dependency injection promotes facades?

I have a Business Layer, whose only one class should be visible to outer world. So, I have marked all classes as internal except that class. Since that class requires some internal class to instantiate, I need other classes to be marked as public and other classes depend on some other classes and so on. So ultimately almost all of my internal classes are made public.
How do You handle such scenarios?
Also today there is just one class exposed to outer world but in future there may be two or three, so it means I need three facades?
Thanks
Correct, all of your injected dependencies must be visible to your Composition Root. It sounds like you're asking this question: Ioc/DI - Why do I have to reference all layers/assemblies in entry application?
To quote part of that answer from Mark Seeman:
you don't have to add hard references to all required libraries. Instead, you can use late binding either in the form of convention-based assembly-scanning (preferred) or XML configuration.
Also this, from Steven:
If you are very strict about protecting your architectural boundaries using assemblies, you can simply move your Composition Root to a separate assembly.
However, you should ask yourself why doing so would be worth the effort. If it is merely to enforce architectural boundaries, there is no substitute for discipline. My experience is that that discipline is also more easily maintained when following the SOLID principles, for which dependency injection is the "glue".
After doing a lot of research I am writing my findings, so that it may be of some help to newcomers on Dependency Injection
Misunderstandings regarding my current design and Dependency Injection:
Initial approach and problem(s) associated with it:
My business layer was having a composition root inside it, where as
it should be outside the business layer and near to the application
entry point. In composition root I was essentially having a big factory referred as Poor Man's DI by Mark Seemann. In my application starting point, I was creating an instance of this factory class and then creating my only (intended to be) visible class to outside world. This decision clearly violates Liskov's Principle which says that every dependency should be replaceable. I was having a modular design, but my previous approach was tightly coupled, I wasn't able to reap more benefits out of it, despite only some code cleanliness and code maintainability.
A better approach is:
A very helplful link given by Facio Ratio
The Composition root should have been near the application root, all dependency classes should be made public which I referred initially as a problem; making them public I am introducing low coupling and following Liskov's substitution which is good.
You can change the public class to the interface and all other parts of the program will only know about the interface. Here's some sample code to illustrate this:
public interface IFacade
{
void DoSomething();
}
internal class FacadeImpl : IFacade
{
public FacadeImpl(Alfa alfa, Bravo bravo)
{
}
public void DoSomething()
{
}
}
internal class Alfa
{
}
internal class Bravo
{
}
I can see three solutions, none real good. You might want to combine them in someway. But...
First, put some simple parameters (numeric, perhaps) in the constructor that let the caller say what he wants to do, and that the new public class instance can use to grab internal class objects (to self-inject). (You could use special public classes/interfaces used solely to convey information here too.) This makes for an awkward and limited interface, but is great for encapsulation. If the caller prefers adding a few quick parameters to constructing complex injectable objects anyway this might work out well. (It's always a drag when a method wants five objects of classes you never heard of before when the only option you need, or even want, is "read-only" vs "editable".)
Second, you could make your internal classes public. Now the caller has immense power and can do anything. This is good if the calling code is really the heart of the system, but bad if you don't quite trust that code or if the caller really doesn't want to be bothered with all the picky details.
Third, you might find you can pull some classes from the calling code into your assembly. If you're really lucky, the class making the call might work better on the inside (hopefully without reintroducing this problem one level up).
Response to comments:
As I understand it, you have a service calling a method in a public class in your business layer. To make the call, it needs objects of other classes in the business layer. These other classes are and should be internal. For example, you want to call a method called GetAverage and pass it an instance of the (internal) class RoundingPolicy so it knows how to round. My first answer is that you should take an integer value instead of a class: a constant value such as ROUND_UP, ROUND_DOWN, NEAREST_INTEGER, etc. GetAverage would then use this number to generate the proper RoundingPolicy instance inside the business layer, keeping RoundingPolicy internal.
My first answer is the one I'm suggesting. However, it gives the service a rather primitive interface, so my second two answers suggest alternatives.
The second answer is actually what you are trying to avoid. My thinking was that if all those internal classes were needed by the service, maybe there was no way around the problem. In my example above, if the service is using 30 lines of code to construct just the right RoundingPolicy instance before passing it, you're not going to fix the problem with just a few integer parameters. You'd need to give the overall design a lot of thought.
The third answer is a forlorn hope, but you might find that the calling code is doing work that could just as easily be done inside the business layer. This is actually similar to my first answer. Here, however, the interface might be more elegant. My first answer limits what the service can do. This answer suggests the service doesn't want to do much anyway; it's always using one identical RoundingPolicy instance, so you don't even need to pass a parameter.
I may not fully understand your question, but I hope there's an idea here somewhere that you can use.
Still more: Forth Answer:
I considered this a sort of part of my first answer, but I've thought it through and think I should state it explicitly.
I don't think the class you're making the call to needs an interface, but you could make interfaces for all the classes you don't want to expose to the service. IRoundingPolicy, for instance. You will need some way to get real instances of these interfaces, because new IRoundingPolicy() isn't going to work. Now the service is exposed to all the complexities of the classes you were trying to hide (down side) but they can't see inside the classes (up side). You can control exactly what the service gets to work with--the original classes are still encapsulated. This perhaps makes a workable version of my second answer. This might be useful in one or two places where the service needs more elaborate options than my first answer allows.

2 Product lines sharing same code

We are working on two product lines that will share the same code.
For functionality that differs, I have both product lines implement the same interface (or base classes in some case) and these types will be created in the Main class (which is separate for both product lines) and passed further downstream.
For code that is deep inside the business logic, it is very hard to have product line specific code. We do not want to user if(ProductLine == "ProductLine1") and else methodology.
So I am planning to implement a Factory class which will have static methods to return NewObject1(), NewObject2() and so on. This Factory class will be registered in the Main class as Factory.RegisterClient(ProductLine1).
So with the above approach, the factory(which internally contains ProductLine1Factor & ProductLine2Factory) knows which type of objects to create.
Do you know a better approach to this problem. Please note that ProductLine1 was already existing and ProductLine2 is something new (but is 90% similar to ProductLine1). We cannot do drastic refactoring such that both product lines exist. We want to do as minimally invasive code changes as possible.
The factory approach typically exposes an interface, but the problem with interfaces is that I cannot expose static types which are also needed.
I would really appreciate if some experts would shed some light.
Your approach sounds fine.
Instead of a custom crafted factory, why don't you use a fully fledged IoC framework like NInject or Unity? You could have the service implemented twice, for each client, and select one in a container configuration file, statically. This way you don't even need to change the single line of your code if you add yet another implementation, you just reconfigure i.e. make some changes in the xml file.
Anyway, an IoC container is just a tool, use it or not, it just replaces your factory (IoC containers are sometimes called "factories on steroids").

Design - Dependency Hell Solution?

We use an MVC architecture with a model consisting of a BLL and DAL.
So we develop "modules" for our system and the particular one I am implementing makes use of alot of the same dependencies. One class in particular has 20 dependencies. Currently the default constructor is creating a default concrete implementation, and we also have a second constructor [that the first one uses] that allows one to inject there own dependencies (i.e. testing.)
20 constructor arguments seems like a pretty nasty code smell.
The other annoying thing is that often when I starting to add common functionality, I need to go add constructor code and fields in every class often repeating the same kinds of code over and over again.
An IoC container seems like a natural solution to this, but the problem is how far do I go? Do I include the DAL dependencies and the BLL dependencies? What about "helper" or "service" dependencies? It seems like at a certain point I am just recreating the "namespace" structure with the ability to reference my classes like static classes at which point I question what I am actually gaining.
I am having trouble thinking through this. Does anyone have an elegant solution or advice?
If you go the IoC route (which I recommend) I would include all your dependencies in the container.
The benefit is that you never have to worry about creating those dependencies, even if there are a ton of them many layers deep.
e.g ClassA takes in 4 other classes in it's constructor, each of those takes in two others in theirs, and each of those takes in at least a DAL reference.
In that case you just need to reference the IoC in your highest-level layer (the "composition root"), which could be your UI, and say "give me an instance of object A", then the IoC will automagically instantiate the other 20 instances for the various dependencies needed to construct the object graph.
Your classes no longer need to worry about how to create their dependencies, if they need something they just stick it in the constructor and the IoC will ensure it gets it.
I would also comment that 20 dependencies in one class is a definite code smell even if you're using IoC. It usually indicates that class is doing far too much stuff and violates the Single Responsibility Principle.

Problems faced when trying to apply good Dependency Injection practice

I've been using IoC (mostly Unity) and Dependency Injection in .NET for some time now and I really like the pattern as a way to encourage creation of software classes with loose coupling and which should be easier to isolate for testing.
The approach I generally try to stick to is "Nikola's Five Laws of IoC" - in particular not injecting the container itself and only using constructor injection so that you can clearly see all the dependencies of a class from its constructor signature. Nikola does have an account on here but I'm not sure if he is still active.
Anyway, when I end up either violating one of the other laws or generally ending up with something that doesn't feel or look right, I have to question whether I'm missing something, could do it better, or simply shouldn't be using IoC for certain cases. With that in mind here are a few examples of this and I'd be grateful for any pointers or further discussion on these:
Classes with too many dependencies. ("Any class having more then 3 dependencies should be questioned for SRP violation"). I know this one comes up a lot in dependency injection questions but after reading these I still don't have any Eureka moment that solves my problems:
a) In a large application I invariably find I need 3 dependencies just to access infrastructure (examples - logging, configuration, persistence) before I get to the specific dependencies needed for the class to get its (hopefully single responsibility) job done. I'm aware of the approach that would refactor and wrap such groups of dependencies into a single one, but I often find this becomes simply a facade for several other services rather than having any true responsibility of its own. Can certain infrastructure dependencies be ignored in the context of this rule, provided the class is deemed to still have a single responsibility?
b) Refactoring can add to this problem. Consider the fairly common task of breaking apart a class that has become a bit big - you move one area of functionality into a new class and the first class becomes dependent on it. Assuming the first class still needs all the dependencies it had before, it now has one extra dependency. In this case I probably don't mind that this dependency is more tightly coupled, but its still neater to have the container provide it (as oppose to using new ...()), which it can do even without the new dependency having its own interface.
c) In a one specific example I have a class responsible for running various different functions through the system every few minutes. As all the functions rightly belong in different areas, this class ends up with many dependencies just to be able to execute each function. I'm guessing in this case other approaches, possibly involving events, should be considered but so far I haven't tried to do it because I want to co-ordinate the order the tasks are run and in some cases apply logic involving outcomes along the way.
Once I'm using IoC within an application it seems like almost every class I create that is used by another class ends up being registered in and/or injected by the container. Is this the expected outcome or should some classes have nothing to do with IoC? The alternative of just having something new'd up within the code just looks like a code smell since its then tightly coupled. This is kind of related to 1b above too.
I have all my container initialisation done at application startup, registering types for each interface in the system. Some are deliberately single instance lifecycles where others can be new instance each time they are resolved. However, since the latter are dependencies of the former, in practice they become a single instance too since they are only resolved once - at construction time of the single instance. In many cases this doesn't matter, but in some cases I really want a different instance each time I do an operation, so rather than be able to make use of the built in container functionality, I'm forced to either i) have a factory dependency instead so I can force this behaviour or ii) pass in the container so I can resolve each time. Both of these approaches are frowned upon in Nikola's guidance but I see i) as the lesser of two evils and I do use it in some cases.
In a large application I invariably find I need 3 dependencies just to access infrastructure (examples - logging, configuration, persistence)
imho infrastructure is not dependencies. I have no problem using a servicelocator for getting a logger (private ILogger _logger = LogManager.GetLogger()).
However, persistence is not infrastructure in my point of view. It's a dependency. Break your class into smaller parts.
Refactoring can add to this problem.
Of course. You will get more dependencies until you have successfully refactored all classes. Just hang in there and continue refactoring.
Do create interfaces in a separate project (Separated interface pattern) instead of adding dependencies to classes.
In a one specific example I have a class responsible for running various different functions through the system every few minutes. As all the functions rightly belong in different areas, this class ends up with many dependencies just to be able to execute each function.
Then you are taking the wrong approach. The task runner should not have a dependency on all tasks that should run, it should be the other way around. All tasks should register in the runner.
Once I'm using IoC within an application it seems like almost every class I create that is used by another class ends up being registered in and/or injected by the container.*
I register everything but business objects, DTOs etc in my container.
I have all my container initialisation done at application startup, registering types for each interface in the system. Some are deliberately single instance lifecycles where others can be new instance each time they are resolved. However, since the latter are dependencies of the former, in practice they become a single instance too since they are only resolved once - at construction time of the single instance.
Don't mix lifetimes if you can avoid it. Or don't take in short lived dependencies. In this case you could use a simple messaging solution to update the single instances.
You might want to read my guidelines.
Let me answer question 3. Having a singletons depend on a transient is a problem that container profilers try to detect and warn about. Services should only depend on other services that have a lifetime that is greater than or equals to that of their own. Injecting a factory interface or delegate to solve this is in general a good solution, and passing in the container itself is a bad solution, since you end up with the Service Locator anti-pattern.
Instead of injecting a factory, you can solve this by implementing a proxy. Here's an example:
public interface ITransientDependency
{
void SomeAction();
}
public class Implementation : ITransientDependency
{
public SomeAction() { ... }
}
Using this definition, you can define a proxy class in the Composition Root based on the ITransientDependency:
public class TransientDependencyProxy<T> : ITransientDependency
where T : ITransientDependency
{
private readonly UnityContainer container;
public TransientDependencyProxy(UnityContainer container)
{
this.container = container;
}
public SomeAction()
{
this.container.Resolve<T>().SomeAction();
}
}
Now you can register this TransientDependencyProxy<T> as singleton:
container.RegisterType<ITransientDependency,
TransientDependencyProxy<Implementation>>(
new ContainerControlledLifetimeManager());
While it is registered as singleton, it will still act as a transient, since it will forward its calls to a transient implementation.
This way you can completely hide that the ITransientDependency needs to be a transient from the rest of the application.
If you need this behavior for many different service types, it will get cumbersome to define proxies for each and everyone of them. In that case you could try Unity's interception functionality. You can define a single interceptor that allows you to do this for a wide range of service types.

Categories

Resources