I am studying IoC, DDD and AOP concepts. I've read a number of articles, docs, Ninject manual (i'm restricted to use .NET 3.5), tried some stuff and so on.
It's hard to shove everything at once to my head, but motivation, concepts and technical matters are somewhat clear. And i'd been always feeling that i was missing something.
Firstly, as i understand IoC containers' purpose is initial object structure set up?
Like, set up container in composition root, create "main" object, that is being wired all the way by IoC container.
Then, as i understand, later all objects are instantiated with factories? Although i can't help myself to perceive factory as a case of service locator (that ended up considered antipattern and by the way is used as core mechanics of IoC containers).
So the question is:
What if i want to create an instance with slightly different structure, e.g. i have
interface IFoo{}
interface IBar{}
class SomeClass
{
SomeClass(IFoo obj){...}
}
class Foo : IFoo
{
Foo(IBar obj){...}
}
class Bar : IBar
{
}
class FooBar : IBar // also implements IBar interface
{
}
So, initial binding configuration is making SomeClass.Foo.Bar structure. Assume, i also need SomeClass.Foo.FooBar. What do i do? The options i can think of:
reconfigure bindings 'in place': just no.
have a constructor parameter for top class, that has configuration for whole structure. that's pretty awful. aside from the fact that all subsequent constructors (and all other project classes constructors, in the end, i'm sure) will have to have one more parameter, it is not clearly seen, how it will function and not use some dirty tricks.
substitute what is needed after object was created. it either breaks law of demeter (about which i'm not concerned too much, but in this case it's too rude) and a couple of other principles or, in general case, isn't possible at all.
use factory that is configured somehow. it just defers/transfers the need itself to later/other place in code
use some kind of contextual/conventional binding. one solution i see (didn't test yet) it's to go all the way to the top of "activation root", check, what's creating the hierarchy. m.b. we'll have to make decorator for top level class, for container to check its type and behave accordingly. actually, container may be configured in a manner, that it decides, what concrete instance to inject by "parsing" top level interface's name. something like
ICfg_ConcreteType1_ConcreteType2_...
the problems here (besides that it looks like hack):
a) we must introduce some mnemonic system, which is not obscene/user friendly.
b) we must have rules/decorators for every factory with this "feature" (but looks like we can somewhat simplify the process at least with rules)
c) it resembles me of reflection usage with convention over configuration, which i'm averted of and treat it as a hack.
Or we may use attributes to set this up. Or may be i just don't know something.
Firstly, as i understand IoC containers' purpose is initial object structure set up?
Forget about IoC containers for a moment. Dependency Injection is not about using tools. It's first and foremost about applying principles and patterns. The driving force behind Dependency Injection are the SOLID principles. I would even go as far as start your application without using an IoC container at all, and only start using one when is a really compelling reason to do so. This means that you simply build up the object graphs by hand. The right place to do this is in your Composition Root. This should be the single place where you compose your object graphs.
And do note that this advice comes from someone who is building and maintaining a IoC container himself.
Then, as i understand, later all objects are instantiated with factories?
When practicing Dependency Injection, you will see that the need to use factories actually minimizes. They can still be useful, but I only use them sparingly nowadays.
Reason for this is that a factory usually just adds an extra (useless) layer of abstraction.
When starting with making code more loosely coupled, developers are tempted to use a factory as follows:
public class SomeClass
{
public void HandleSomething() {
IFoo foo = FooFactory.Create();
foo.DoSomething();
}
}
Although this allows a Foo implementation to be decoupled from SomeClass, SomeClass still takes a strong dependency on FooFactory. This still makes SomeClass hard to test, and lowers reusability.
After experiencing such a problem, developers often start to abstract away the FooFactory class as follows:
public class SomeClass
{
private readonly IFooFactory fooFactory;
public SomeClass(IFooFactory fooFactory) {
this.fooFactory = fooFactory;
}
public void HandleSomething() {
IFoo foo = this.fooFactory.Create();
foo.DoSomething();
}
}
Here a IFooFactory abstraction is used, which is injected using constructor injection. This allows SomeClass to be completely loosely coupled.
SomeClass however now has two external dependencies. It both knows about IFooFactory and IFoo. This duplicates the complexity of SomeClass, while there is no compelling reason to do so. We will immediately notice this increase of complexity when writing unit tests. We will now suddenly have to mock two different abstactions and test them both.
Since we are practicing constructor injection here, we can simplify SomeClass -without any downsides- to the following:
public class SomeClass
{
private readonly IFoo foo;
public SomeClass(IFoo foo) {
this.foo = foo;
}
public void HandleSomething() {
this.foo.DoSomething();
}
}
Long story short, although the Factory design pattern is still valid and useful, you will hardly ever need it for retrieving injectables.
Although i can't help myself to perceive factory as a case of service locator
No. A factory is not a service Locator. The difference between a factory and a locator is that with a factory you can build up only one particular type of objects, while a locator is untyped. You can build up anything. If you use an IoC container however, you will often see that the factory implementation will forward the request to the container. This should not be a problem, because your factory implementation should be part of your composition root. The composition root always depends on your container and this is not a form of Service Location, as Mark Seemann explains here.
Or we may use attributes to set this up. Or may be i just don't know something.
Refrain from using attributes for building up object graphs. Attributes pollute your code base and cause a hard dependency on an underlying technology. You absolutely want your application to stay oblivious to any used composition tool. As I started with, you might not even use any tool at all.
For instance, your object graph can be composed quite easily as follows:
new SomeClass(
new Foo(
new Bar()));
In your example, you seem to have two IBar implementations. From the context it is completely unclear what the function of this abstraction and these implementations are. I assume that you want to be able to switch implementations one some runtime condition. This can typically be achieved by using a proxy implementation. In that case your object graph would look as follows:
new SomeClass(
new Foo(
new BarProxy(
new Bar(),
new FooBar()));
Here BarProxy looks as follows:
public class BarProxy
{
private readonly IBar left;
private readonly IBar right;
public BarProxy(IBar left, IBar right) {
this.left = left;
this.right = right;
}
public void BarMethod(BarOperation op) {
this.GetBar(op).BarMethod(op);
}
private IBar GetBar(BarOperation op) {
return op.SomeValue ? this.left : this.right;
}
}
It's hard to say when you should start using a DI container. Some people like to stay away from DI containers almost always. I found that for the type of applications I build (that are based on these and these patterns), a DI container becomes really valuable, because it saves you from having to constantly update your Composition Root. In other words:
Dependency Injection and the SOLID principles help making your application maintainable. A DI library will help in making your composition root maintainable, but only after you made your application maintainable using SOLID and DI.
You would generally use some sort of tag system.
http://www.ghij.org/blog/post/2014/05/19/how-to-tag-classes-to-determine-which-to-reflect-with-mef.aspx
Related
I have a class where I am injecting two service dependencies. I am using Unity container.
public interface IOrganizer
{
void Method1();
void Method2();
void Method3();
}
public class Organizer : IOrganizer
{
private IService1 _service1;
private IService2 _service2;
public Organizer(Iservice1 service1, IService2 service2)
{
_service1 = service1;
_service2 = service2;
}
public void Method1()
{
/*makes use of _service1 and _service2 both to serve the purpose*/
}
public void Method2()
{
/*makes use of only _service1 to serve the purpose*/
}
public void Method3()
{
/*makes use of only _service2 to serve the purpose*/
}
}
While it all works, but somehow it smells because when I am only invoking Method2 and Method3, unity unnecessarily creates an instance of another not required service. The code snippet here is just a sample for explanation purposes. In a real situation object graph of these injected services itself is quite deep.
Is there a better way to design and address this kind of scenario?
I think your sense of smell is competent. Most people would happily code like this without a second thought. I do agree, though, that there's a few code smells in a design like outlined in the OP.
I'd like to point out that I use the term code smell as in Refactoring. It's an indication that something may not be right, and it might be worthwhile to investigate further. Sometimes, such investigation reveals that there are good reasons that the code is as it is, and you move on.
There's at least two separate smells in the OP. They're unrelated, so I'll treat each one separately.
Cohesion
A fundamental, but often forgotten concept of object-oriented design is that of cohesion. Think of it as a counter-force to separation of concerns. As Kent Beck once put it (the exact source escapes me, so I paraphrase), things that vary together, belong together, while things that vary independently should be separated.
Without the 'force' of cohesion, the 'force' of separation of concerns would pull code apart until you have extraordinarily small classes, and even simple business logic is spread across multiple files.
One way to look for cohesion, or lack thereof, is to 'count' how many class fields are being used by each method of a class. While only a crude indicator, it does trigger our sense of smell in the OP code.
Method1 uses both class fields, so is no cause for concern. Both Method2 and Method3, on the other hand, use only half of the class fields, so we could view that as indication of poor cohesion - a code smell, if you will.
How can you address that? Again, I wish to emphasise that a smell isn't guaranteed to be bad. It's only a reason to investigate.
Still, if you want to address the issue, I can't think of any other way than breaking up the class into several smaller classes.
The Organizer class in the OP implements the IOrganizer interface, so technically, breaking up Organizer is only possible if you can also break up the interface - although you could write a Facade, and then delegate each method to a separate class that implements that particular method.
Still, the presence of an interface emphasises the importance of the Interface Segregation Principle. I often see code bases exhibit this particular problem because the interfaces are too big. If at all possible, make the interfaces as small as possible. I tend to take it to the extreme and define only a single member on each interface.
From another of the SOLID principles, the Dependency Inversion Principle, follows that interfaces should be defined by the clients that use them, not the classes that implement them. Designing interfaces like that often enables you to keep them small, and to the point.
Recall also that a single class can implement multiple interfaces.
Performance
Another concern regarding the design in the OP is of performance, although I agree with NightOwl888's comment that you're likely in micro-optimisation territory.
In general, you can compose even large object graphs with confidence. As NightOwl888 also suggests in the comments above, if a dependency has Singleton lifetime, it makes little difference if you inject it, but then end up not using it.
Even if you can't give a dependency like _service2 Singleton lifetime, I again agree with NightOwl888 that object creation in .NET is fast to the point where you almost can't measure it. And as he also points out, Injection Constructors should be simple.
Even in the rare case where a dependency must have Transient lifetime, and for whatever reason creating an instance is expensive, you can always hide that dependency behind a Virtual Proxy, as I also describe in the article about object graphs.
How you configure all that in Unity, I no longer remember, but if Unity can't deal with that, choose another method of composition, preferably Pure DI.
As long as you're using Unit 3 or higher, you don't need to do anything special for resolving lazy.
You register your type like you normally would:
container.RegisteryType<IMyInterface>()...;
And then change the constructor to require lazy:
public class MyClass
{
public Lazy<IMyInterface> _service1;
public MyClass(Lazy<IMyInterface> service1)
{
_serivce1 = service1;
}
}
Then call whatever you method you need:
_service1.Value.MyMethod();
So Dependency Injection is recommended usually to help with unit testing, to solve the problem of having a class dependent on other classes. This sounds great, but let me walk through the issue I'm facing.
Here is a regular implementation without DI:
class Upper{
Middle middle = new Middle();
}
class Middle{
Lower lower = new Lower();
}
class Lower{
}
Now let's start at the bottom. Middle depends on Lower, we don't really want that, so we'll create a redundant interface for Lower and pass that to the constructor of Middle instead:
class Middle{
Lower lower;
public Middle(ILower lower){
this.lower = lower;
}
}
interface ILower{
}
class Lower : ILower{
}
Well this sounds great, right? Well not really. Most examples I've seen stop here, forgetting that something needs to use the class Middle. Now we have to update Upper to be compatible:
class Upper{
Middle middle = new Middle(new Lower());
}
This doesn't seem very useful... All that we've done is moved the problem up a level, and created an unusual dependency: Upper depends on Lower now? That's definitely not an improvement.
I must be missing the benefit, but it seems like DI just moved the issue rather than solved it. In fact, it also makes the code harder to understand.
Also, here is a "full" implementation:
interface IUpper {
}
class Upper : IUpper {
Middle middle;
public Upper(IMiddle middle){
this.middle = middle;
}
}
interface IMiddle {
}
class Middle : IMiddle {
Lower lower;
public Middle(ILower lower){
this.lower = lower;
}
}
interface ILower {
}
class Lower : ILower {
}
But again, I'm just moving the problem. To use Upper, I need:
new Upper(new Middle(new Lower()));
and now I depend on 3 classes!
Dependency injection simply refers to the way you create classes, so that their dependencies are provided for them ("injected" into them) instead of classes creating instances of their own dependencies.
Does DI just move the problem of creating class instances somewhere else?
Yes, that's exactly what it does, and that's good.
Every class instance that you use has to be instantiated somewhere. The question is where that instantiation takes place, and whether it makes your classes more or less manageable and testable.
The trade-off is that if one class directly creates instances of other classes it depends on, then sure, calling the constructor for that outer class is much simpler. You create that class, and it creates a bunch of other classes, and they create more classes, and so on. But each class that directly creates other classes becomes harder and harder to unit test. You can't write a test for just the behavior of one class when that behavior includes the behavior of the classes it creates, the classes they create, and so on. So in return for simpler constructor calls, you get code which is just about impossible to test and also very difficult to maintain.
Dependency injection moves creation of a class's dependencies out of the class. That makes each individual class easier to test and maintain, but it creates a different problem, as you've observed. Now your constructor calls are much more complicated, creating all sorts of nested dependencies.
What solves that problem is a dependency injection container, also called an IoC container. Some examples are Windsor, Autofac, Unity, and there are many more. With these, you simply specify an implementation for each individual interface on which any class might depend.
For example (this is Windsor syntax, but they're all somewhat similar)
container.Register(Component.For<InterfaceA, ImplementationToUse>());
container.Register(Component.For<InterfaceB, ImplementationForThis>());
container.Register(Component.For<InterfaceC, ImplementationToUse>());
Then, if you call
var thingINeed = container.Resolve<InterfaceA>();
(That's not actually how we get a class instance from a container, but that's another story.)
It's going to figure out which classes it needs to create to pass the the constructor of the implementation. If those classes have more dependencies, it will create those, and so on, and so on.
So now you've got the best of both worlds. You can create as many small, testable classes as you want, with tons of nested dependencies, all depending on abstractions. If you were to try to call their constructors directly it would be insanely complicated, way beyond the example in your question. But you don't have to do that. You can just think of each class individually - what does it do, and what interfaces does it directly depend on?
You still have some complexity. Instead of calling a bunch of constructors you now have to register individual dependencies with a container. But it's a good trade-off, and you come out ahead because your classes are decoupled and testable.
When you inject dependencies, you are not exempt from the need to instantiate classes. You take the creation of dependencies out of dependent classes so that they do not depend on their specific implementation (calling the constructor of the aggregated class).
Yes, putting dependencies on the upper level, you get this line:
new Upper(new Middle(new Lower()));
To create an object, you need to resolve the tree of its dependencies. To facilitate this work, there are many IoC containers. They allow you to reduce the recording to this:
var upper = iocContainer.resolve<IUpperInterface>();
As advantages, you get class testability, flexibility and re-useability.
How do I register types which take another registered type as a parameter and also simple types (like an integer)?
public interface IDeviceManager
{
// implementation omitted.
}
public class DeviceManager : IDeviceManager
{
public DeviceManager(IDeviceConfigRepository configRepo, int cacheTimeout)
{
// implementation omitted
}
}
I do have a container registration for the IDeviceConfigRepository. That's ok. But how do I create an instance of DeviceManager with the configured dependency and passing along an integer of my choice in composition root?
I thought about creating a factory.
public class DeviceManagerFactory : IDeviceManagerFactory
{
private readonly Container _container;
public DeviceManagerFactory(Container container)
{
_container = container;
}
public DeviceManager Create(int minutes)
{
var configRepo = _container.GetInstance<IDeviceConfigurationRepository>();
return new DeviceManager(configRepo, minutes);
}
}
This is pretty simple.
However now I do not have a registration for DeviceManager which is the type I ultimately need. Should I change these dependencies to the factory instead?
public class ExampleClassUsingDeviceManager
{
private readonly DeviceManager _deviceManager;
public ExampleClassUsingDeviceManager(DeviceManager deviceManager, ...)
{
_deviceManage = deviceManager;
}
// actions...
}
For this to work and to avoid circular dependencies I would probably have to move the factory from the "application" project (as opposed to class libraries) where the composition root is to the project where the DeviceManager is implemented.
Is that OK? It would of course mean passing around the container.
Any other solutions to this?
EDIT
In the same project for other types I am using parameter objects to inject configuration into my object graph. This works OK since I only have one class instance per parameter object type. If I had to inject different parameter object instances (for example MongoDbRepositoryOptions) into different class instances (for example MongoDbRepository) I would have to use some kind of named registration - which SimpleInjector doesn't support. Even though I only have one integer the parameter object pattern would solve my problem. But I'm not too happy about this pattern knowing it will break as soon as I have multiple instances of the consuming class (i.e. MongoDbRepository).
Example:
MongoDbRepositoryOptions options = new MongoDbRepositoryOptions();
MongoDbRepositoryOptions.CollectionName = "config";
MongoDbRepositoryOptions.ConnectionString = "mongodb://localhost:27017";
MongoDbRepositoryOptions.DatabaseName = "dev";
container.RegisterSingleton<MongoDbRepositoryOptions>(options);
container.RegisterSingleton<IDeviceConfigurationRepository, MongoDbRepository>();
I am excited to hear how you deal best with configurations done at composition root.
Letting your DeviceManagerFactory depend on Container is okay, as long as that factory implementation is part of your Composition Root.
Another option is to inject the IDeviceConfigRepository into the DeviceManagerFactory, this way you can construct a DeviceManager without the need to access the container:
public class DeviceManagerFactory : IDeviceManagerFactory {
private readonly IDeviceConfigurationRepository _repository;
public DeviceManagerFactory(IDeviceConfigurationRepository repository) {
_repository = repository;
}
public DeviceManager Create(int minutes) {
return new DeviceManager(_repository, minutes);
}
}
However now I do not have a registration for DeviceManager which is the type I ultimately need. Should I change these dependencies to the factory instead?
In general I would say that factories are usually the wrong abstraction, since they complicate the consumer instead of simplifying them. So you should typically depend on the service abstraction itself (instead of depending on a factory abstraction that can produces service abstraction implementations), or you should inject some sort of proxy or mediator that completely hides the existence of the service abstraction from point of view of the consumer.
#DavidL points at my blog post about runtime data. I'm unsure though whether the cacheTimeout is runtime data, although you seem to be using it as such, since you are passing it in into the Create method of the factory. But we're missing some context here, to determine what's going on. My blog post still stands though, if it is runtime data, it's an anti-pattern and in that case you should
pass runtime data through method calls of the API
or
retrieve runtime data from specific abstractions that allow resolving runtime data.
UPDATE
In case the value you are using is an application constant, that is read through the configuration file, and doesn't change during lifetime of the application, it is perfectly fine to inject it through the constructor. In that case it is not a runtime value. There is also no need for a factory.
There are multiple ways to register this in Simple Injector, for instance you can use a delegate to register the DeviceManager class:
container.Register<DeviceManager>(() => new DeviceManager(
container.GetInstance<IDeviceConfigRepository>(),
cacheTimeout: 15));
Downside of this approach is that you lose the ability of Simple Injector to auto-wire the type for you, and you disable Simple Injector's ability to verify, diagnose and visualize the object graph for you. Sometimes this is fine, while other times it is not.
The problem here is that Simple Injector blocks the registration of primitive types (because they cause ambiguity) while not presenting you with a clean way to make the registration. We are considering (finally) adding such feature in v4, but that doesn't really address your current needs.
Simple Injector doesn't easily allow you to specify a primitive dependency, while letting the container auto-wire the rest. Simple Injector's IDependencyInjectionBehavior abstraction allows you to override the default behavior (which is to disallow doing this). This is described here, but I usually advice against doing this, because it is usually requires quite a lot of code.
There are basically two options here:
Abstract the specific logic that deals with this caching out of the class and wrap it in a new class. This class will have just the cacheTimeout as its dependency. This is of course only useful when there actually is logical to abstract and is usually only logical when you are injecting that primitive value into multiple consumers. For instance, instead of injecting a connectionstring into multiple classes, you're probably better of injecting an IConnectionFactory into those classes instead.
Wrap the cacheTimeout value into a complex data container specific for the consuming class. This enables you to register that type, since it resolves the ambiguity issue. In fact, this is what you yourself are already suggesting and I think this is a really good thing to do. Since those values are constant at runtime, it is fine to register that DTO as singleton, but make sure to make it immutable. When you give each consumer its own data object, you won't have to register multiple instances of those, since they are unique. Btw, although named registations aren't supported, you can make conditional or contextual registrations using RegisterConditional and there are other ways to achieve named registrations with Simple Injector, but again, I don't think you really need that here.
I most commonly am tempted to use "bastard injection" in a few cases. When I have a "proper" dependency-injection constructor:
public class ThingMaker {
...
public ThingMaker(IThingSource source){
_source = source;
}
But then, for classes I am intending as public APIs (classes that other development teams will consume), I can never find a better option than to write a default "bastard" constructor with the most-likely needed dependency:
public ThingMaker() : this(new DefaultThingSource()) {}
...
}
The obvious drawback here is that this creates a static dependency on DefaultThingSource; ideally, there would be no such dependency, and the consumer would always inject whatever IThingSource they wanted. However, this is too hard to use; consumers want to new up a ThingMaker and get to work making Things, then months later inject something else when the need arises. This leaves just a few options in my opinion:
Omit the bastard constructor; force the consumer of ThingMaker to understand IThingSource, understand how ThingMaker interacts with IThingSource, find or write a concrete class, and then inject an instance in their constructor call.
Omit the bastard constructor and provide a separate factory, container, or other bootstrapping class/method; somehow make the consumer understand that they don't need to write their own IThingSource; force the consumer of ThingMaker to find and understand the factory or bootstrapper and use it.
Keep the bastard constructor, enabling the consumer to "new up" an object and run with it, and coping with the optional static dependency on DefaultThingSource.
Boy, #3 sure seems attractive. Is there another, better option? #1 or #2 just don't seem worth it.
As far as I understand, this question relates to how to expose a loosely coupled API with some appropriate defaults. In this case, you may have a good Local Default, in which case the dependency can be regarded as optional. One way to deal with optional dependencies is to use Property Injection instead of Constructor Injection - in fact, this is sort of the poster scenario for Property Injection.
However, the real danger of Bastard Injection is when the default is a Foreign Default, because that would mean that the default constructor drags along an undesirable coupling to the assembly implementing the default. As I understand this question, however, the intended default would originate in the same assembly, in which case I don't see any particular danger.
In any case you might also consider a Facade as described in one of my earlier answers: Dependency Inject (DI) "friendly" library
BTW, the terminology used here is based on the pattern language from my book.
My trade-off is a spin on #BrokenGlass:
1) Sole constructor is parameterized constructor
2) Use factory method to create a ThingMaker and pass in that default source.
public class ThingMaker {
public ThingMaker(IThingSource source){
_source = source;
}
public static ThingMaker CreateDefault() {
return new ThingMaker(new DefaultThingSource());
}
}
Obviously this doesn't eliminate your dependency, but it does make it clearer to me that this object has dependencies that a caller can deep dive into if they care to. You can make that factory method even more explicit if you like (CreateThingMakerWithDefaultThingSource) if that helps with understanding. I prefer this to overriding the IThingSource factory method since it continues to favor composition. You can also add a new factory method when the DefaultThingSource is obsoleted and have a clear way to find all the code using the DefaultThingSource and mark it to be upgraded.
You covered the possibilities in your question. Factory class elsewhere for convenience or some convenience within the class itself. The only other unattractive option would be reflection-based, hiding the dependency even further.
One alternative is to have a factory method CreateThingSource() in your ThingMaker class that creates the dependency for you.
For testing or if you do need another type of IThingSource you would then have to create a subclass of ThingMaker and override CreateThingSource() to return the concrete type you want. Obviously this approach only is worth it if you mainly need to be able to inject the dependency in for testing, but for most/all other purposes do not need another IThingSource
I vote for #3. You'll be making your life--and the lives of other developers--easier.
If you have to have a "default" dependency, also known as Poor Man’s Dependency Injection, then you have to initialize and "wire" the dependency somewhere.
I will keep the two constructors but have a factory just for the initialization.
public class ThingMaker
{
private IThingSource _source;
public ThingMaker(IThingSource source)
{
_source = source;
}
public ThingMaker() : this(ThingFactory.Current.CreateThingSource())
{
}
}
Now in the factory create the default instance and allow the method to be overrided:
public class ThingFactory
{
public virtual IThingSource CreateThingSource()
{
return new DefaultThingSource();
}
}
Update:
Why using two constructors:
Two constructors clearly show how the class is intended to be used. The parameter-less constructor states: just create an instance and the class will perform all of it's responsibilities. Now the second constructor states that the class depends of IThingSource and provides a way of using an implementation different than the default one.
Why using a factory:
1- Discipline: Creating new instances shouldn't be part of the responsibilities of this class, a factory class is more appropriate.
2- DRY: Imagine that in the same API other classes also depend on IThingSource and do the same. Override once the factory method returning IThingSource and all the classes in your API automatically start using the new instance.
I don't see a problem in coupling ThingMaker to a default implementation of IThingSource as long as this implementation makes sense to the API as a whole and also you provide ways to override this dependency for testing and extension purposes.
You are unhappy with the OO impurity of this dependency, but you don't really say what trouble it ultimately causes.
Is ThingMaker using DefaultThingSource in any way that does not conform to IThingSource? No.
Could there come a time where you would be forced to retire the parameterless constructor? Since you are able to provide a default implementation at this time, unlikely.
I think the biggest problem here is the choice of name, not whether to use the technique.
The examples usually related to this style of injection are often extremely simplisitic: "in the default constructor for class B, call an overloaded constructor with new A() and be on your way!"
The reality is that dependencies are often extremely complex to construct. For example, what if B needs a non-class dependency like a database connection or application setting? You then tie class B to the System.Configuration namespace, increasing its complexity and coupling while lowering its coherence, all to encode details which could simply be externalized by omitting the default constructor.
This style of injection communicates to the reader that you have recognized the benefits of decoupled design but are unwilling to commit to it. We all know that when someone sees that juicy, easy, low-friction default constructor, they are going to call it no matter how rigid it makes their program from that point on. They can't understand the structure of their program without reading the source code for that default constructor, which isn't an option when you just distribute the assemblies. You can document the conventions of connection string name and app settings key, but at that point the code doesn't stand on its own and you put the onus on the developer to hunt down the right incantation.
Optimizing code so those who write it can get by without understanding what they are saying is a siren song, an anti-pattern that ultimately leads to more time lost in unraveling the magic than time saved in initial effort. Either decouple or don't; keeping a foot in each pattern diminishes the focus of both.
For what it is worth, all the standard code I've seen in Java does it like this:
public class ThingMaker {
private IThingSource iThingSource;
public ThingMaker() {
iThingSource = createIThingSource();
}
public virtual IThingSource createIThingSource() {
return new DefaultThingSource();
}
}
Anybody who doesn't want a DefaultThingSource object can override createIThingSource. (If possible, the call to createIThingSource would be somewhere other than the constructor.) C# does not encourage overriding like Java does, and it might not be as obvious as it would be in Java that the users can and perhaps should provide their own IThingSource implementation. (Nor as obvious how to provide it.) My guess is that #3 is the way to go, but I thought I would mention this.
Just an idea - perhaps a bit more elegant but sadly doesn't get rid of the dependency:
remove the "bastard constructor"
in the standard constructor you make the source param default to null
then you check for source being null and if this is the case you assign it "new DefaultThingSource()" otherweise whatever the consumer injects
Have an internal factory (internal to your library) that maps the DefaultThingSource to IThingSource, which is called from the default constructor.
This allows you to "new up" the ThingMaker class without parameters or any knowledge of IThingSource and without a direct dependency on DefaultThingSource.
For truly public APIs, I generally handle this using a two-part approach:
Create a helper within the API to allow an API consumer to register "default" interface implementations from the API with their IoC container of choice.
If it is desirable to allow the API consumer to use the API without their own IoC container, host an optional container within the API that is populated the same "default" implementations.
The really tricky part here is deciding when to activate the container #2, and the best choice approach will depend heavily on your intended API consumers.
I support option #1, with one extension: make DefaultThingSource a public class. Your wording above implies that DefaultThingSource will be hidden from public consumers of the API, but as I understand your situation there's no reason not to expose the default. Furthermore, you can easily document the fact that outside of special circumstances, a new DefaultThingSource() can always be passed to the ThingMaker.
I'm trying to get my feet wet with unit testing. I'm currently not in the habit of writing interfaces for classes unless I foresee some reason I would need to swap in a different implementation. Well, now I foresee a reason: mocking.
Given that I'm going to be going from just a handful of interfaces to perhaps hundreds, the first thing that popped into my head was, Where should I put all these interfaces? Do I just mix them in with all the concrete implementations or should I put them in a sub-folder. E.g., should controller interfaces go in root/Controllers/Interfaces, root/Controllers, or something else entirely? What do you advise?
Before I discuss organization:
Well, now I foresee a reason: mocking.
You can mock with classes, as well. Subclassing works well for mocking as an option instead of always making interfaces.
Interfaces are incredibly useful - but I would recommend only making an interface if there is a reason to make an interface. I often see interfaces created when a class would work fine and be more appropriate in terms of logic. You shouldn't need to make "hundreds of interfaces" just to allow yourself to mock out implementations - encapsulation and subclassing works quite well for that.
That being said - I typically will organize my interfaces along with my classes, as grouping related types into the same namespaces tends to make the most sense. The main exception is with internal implementations of interfaces - these can be anywhere, but I will sometimes make an "Internal" folder + an Internal namespace that I use specifically for "private" interface implementations (as well as other classes that are purely internal implementation). This helps me keep the main namespace uncluttered, so the only types are the main types relating to the API itself.
Here's a suggestion, if almost all of your interfaces are to support only one class, just add the interface to the same file as the class itself under the same namespace. That way you don't have a separate file for the interface which could really clutter the project or need a sub folder just for interfaces.
If you find yourself creating different classes using the same interface, I would break the interface out into the same folder as the class unless it becomes completely unruly. But I don't think that would happen because I doubt you have hundreds of class files in the same folder. If so, that should be cleaned up and subfoldered according to functionality and the rest will take care of itself.
Coding to interfaces goes far beyond being able to test code. It creates flexibility in the code allowing a different implementation to be swapped in or out depending on product requirements.
Dependency Injection is another good reason to code to interfaces.
If we have an object called Foo that is used by ten customers and now customer x wants to have Foo work in a different way. If we have coded to an interface (IFoo) we just need to implement IFoo to the new requirements in CustomFoo. As long as we don't change IFoo there is not much needed. Customer x can use the new CustomFoo and other customers can continue to use old Foo and there need be few other code changes to accommodate.
However the point I really wanted to make is that interfaces can help eliminate circular references. If we have an object X that has a dependency on object Y and object Y has a dependency on object X. We have two options 1. with object x and y have to be in the same assembly or 2. we have to find some way of breaking the circular reference. We can do this by sharing interfaces rather than sharing implementations.
/* Monolithic assembly */
public class Foo
{
IEnumerable <Bar> _bars;
public void Qux()
{
foreach (var bar in _bars)
{
bar.Baz();
}
}
/* rest of the implmentation of Foo */
}
public class Bar
{
Foo _parent;
public void Baz()
{
/* do something here */
}
/* rest of the implementation of Bar */
}
If foo and bar have completely different uses and dependencies we probably do not want them in the same assembly especially if that assembly is already large.
To do this we can create an interface on one of the classes, say Foo, and refer to the interface in Bar. Now we can put the interface in a third assembly shared by both Foo and Bar.
/* Shared Foo Assembly */
public interface IFoo
{
void Qux();
}
/* Shared Bar Assembly (could be the same as the Shared Foo assembly in some cases) */
public interface IBar
{
void Baz();
}
/* Foo Assembly */
public class Foo:IFoo
{
IEnumerable <IBar> _bars;
public void Qux()
{
foreach (var bar in _bars)
{
bar.Baz();
}
}
/* rest of the implementation of Foo */
}
/* Bar assembly */
public class Bar:IBar
{
IFoo _parent;
/* rest of the implementation of Bar */
public void Baz()
{
/* do something here */
}
I think there is also an argument for maintaining the interfaces separate from their implementations and treating these sightly differently in the release cycle as this allows interoperability between components that were not all compiled against the same sources. If fully coding to interfaces and if interfaces can only be changed for major version increments and not on minor version increments then any component components of the same major version should work with any other component of the same major version regardless of the minor version.
This way you can have a library project with a slow release cycle containing just interfaces, enums and exceptions.
It depends. I do this: If you have to add a dependent 3rd party assembly, move the concrete versions out to a different class library. If not, they can stay side byside in the same directory and namespace.
I find that when I need hundreds of interfaces in my project to isolate dependencies, I find that there may be an issue in my design. This is especially the case when a lot of these interfaces end up having only one method. An alternative to doing this is to have your objects raise events and then bind your dependencies to those events. For an example, let's say you want to mock out persisting your data. One perfectly reasonable way to do this would be to do this:
public interface IDataPersistor
{
void PersistData(Data data);
}
public class Foo
{
private IDataPersistor Persistor { get; set; }
public Foo(IDataPersistor persistor)
{
Persistor = persistor;
}
// somewhere in the implementation we call Persistor.PersistData(data);
}
Another way you could do this without using interfaces or mocks would be do do this:
public class Foo
{
public event EventHandler<PersistDataEventArgs> OnPersistData;
// somewhere in the implementation we call OnPersistData(this, new PersistDataEventArgs(data))
}
Then, in our test, you can instead of creating a mock do this:
Foo foo = new Foo();
foo.OnPersistData += (sender, e) => { // do what your mock would do here };
// finish your test
I find this to be cleaner than using mocks excessively.
I disagree quite a bit with the Accepted answer.
1: While technically correct, you do not NEED an interface because you have the option to mock a concrete implementation, you should make an interface for 2 reasons.
You can extend your code with an interface, concrete implementations require modification, if you do not have an extension, once you get a change request.
1.1:
You can make TDD(Test driven development) without any actual implemented code, as long as you only create interfaces to test. This will also force you to consider code design before you make an implementation. Which is an excellent approach to coding.
1.2:
but I would recommend only making an interface if there is a reason to make an interface. I often see interfaces created when a class would work fine and be more appropriate in terms of logic.
There is always a reason to make an interface. Because SOLID's open/close principle says you should aim for extending your code rather than modifying it.
And this is true for multiple reasons.
1.2.1:
It's easier to write new unit tests this way. You will only need the dependency to the concrete implementation you are testing in your code as a subject. (And before you have a concrete implementation you can use a mock)
1.2.2:
When you have a concrete implementation, the reference to that concrete implementation will be propagated throughout the system. With an interface, all references will be done by interface, not concrete implementation. This makes extension possible.
1.2.3
If you follow up with all "leaf" piece of code, to follow the principle, if the method has a return, the method can't have a side effect, if the method doesn't have a return, it can only have 1 side effect, you will also automatically split your code up into the "S" part of SOLID, this makes your unit tests small, and very easy to maintain.
2:
Interfaces are technically needed, if you want to write clean code. If you want to follow SOLID, I don't see how you can do it, without interfaces.
You will also need to organize your code efficiently when you break about responsibilities, as the more decoupled your code is, the more interfaces and implementations of interfaces, you will have. Thus you need to have a good project management system in place, so you don't have "hundres of interfaces" lying around randomly.
There are so very good guides in books and youtube, udemy, etc. That will teach you this. (and also some poor ones, basically, they increase in usefulness when you have to pay for them in general). You will have to know enough about the subject matter to identify if a free one is good enough, if you plan to make business decision on it, before you do so, at least.