I'm trying to understand SOLID principles, in particular The Dependency Inversion Principle.
In this is SO answer it is explained very well.
I think I have understood that I can't create any instance of a class inside my class. Is it right?
But if I have to save to disk some content, can I create an instance of System.IO.File or do I have to inject it?
I don't understand where is the limit, if I can't instance my own classes or if I can't either instance .NET Framework classes (or whatever other framework).
UPDATE:
I think File is a bad example because is declared as static.
By the way, does this principle apply to static classes?
The S of SOLID stands for SRP (Single Responsibility Principle). You won't violate it by using System.IO.File inside a class directly, once you keep that class with one single responsibility.
It's a good idea trying to abstract the purpose behind using System.IO.File. Let's suppose you need it to generate a log. Then you would probably do something like:
public interface IMyLogger
{
void GenerateLog(IEnumerable<string> content);
}
public class FileLogger: IMyLogger
{
public void GenerateLog(IEnumerable<string> content)
{
System.IO.File.WriteAllLines("C:/Log", content);
}
}
Maybe it's not just a log, it's something more important, like generating a file so other system/app (even external) read it and do some job.
If you are trying to use a DDD approach, the interface could belong to your domain, and the implementation could belong in the application. Then you register your interface as a service and inject it.
The class which needs an IMyLogger actually doesn't need to know how is the log being generated, it just needs the job to be done.
You can apply the same idea when you need to send an email inside some business logic in your domain. Instead of making a connection to an Exchange inside your domain directly, create an interface INotifier and a MailNotifier implementing it to be injected.
Somewhere down the chain of dependencies you will need to use the concrete class directly. Even if you use a DI framework like Ninject, the framework itself will create an instance of the concrete type, so it will not be injected into the framework (which wouldn't make sense, of course).
You can only abstract something away to a certain level. It will vary from project to project - you have to ask yourself if you need another level of abstraction (be it for modularity, unit testing etc.). I think this is very important - you want to be pragmatic, not create layers upon layers of abstractions just for the sake of it.
By the way, does this principle apply to static classes?
Yes, it does. But with static classes you have to introduce a wrapper, which will delegate calls to the static class, because a static class cannot implement interfaces.
There is no point in applying a principle just for the sake of it. Think in a pragmatic way.
If you want to unit-test a method that uses hard coded file accesses, your unit tests will access these files. This is usually not desired as you must set up or clean up these files. To avoid this, you would inject a service which wraps these file accesses. This allows you to replace the real service with a fake one during the unit tests. This fake service can provide hard coded test data for read accesses and dump written data to memory for later analysis or simply do nothing. Btw.: NSubstitute can create fake services at runtime easily.
The injection of services allows you to achieve Unit Test Isolation. E.g. you can test some logic without depending on correct file handling or database accesses or the correct functioning of other services. Injecting a service is just one way to do it. You could also just specify a method parameter as IEnumerable<string> with the content of the file instead. Events can also be used for decoupling. Instead of writing to a log, you could raise a log event.
Most DI frameworks allow you to specify the lifetime of objects. One of these options is Singleton, which means that the DI container will always return the same instance of a requested service. This allows you to wrap static classes in a service that behaves statically.
Related
This is more an architectural question:
Do you use ILogger (and pass it in the constructor via DI) or do you prefer a static class Log?
We use ILogger a lot but it really seems to clatter the code especially when it is passed via constructor. If not passed via constructor and just every time created, then I really do not see a benefit if using the interface.
So how do you handle this? I am especially interested in the arguments behind it - not just saying "static" or "interface".
Thx
Using a static instance of anything is a bad idea for different reasons, depending on your use case.
- They are difficult to mock in a unit test so your logger is always writing logs even when they are not needed.
- Lack of mocking also means you cannot write tests to ensure an error log is written in appropriate situations.
- They cannot be replaced at runtime to allow injection of different loggers. This can be important if you are releasing a library for others to use. I define a standard logger interface and log everything to that, then allow clients to inject their own logger as long as it implements my interface.
- If you use the default static Log implementation provided by the vendor, you are locked into their interface meaning you cannot hide or change the surface area of the logger. Changing loggers becomes a MUCH bigger effort if the syntax of the new logger changes.
So that leaves you with some kind of injection. Personally I prefer having all dependencies in the constructor, even if it becomes verbose, because it’s easy to see all dependencies a particular class has. If you are trying to avoid a big constructor you can look into Property Injection. This requires an attribute on a property of the class, but still gives you all the advantages of injecting the dependencies. If you put the injected property on a base class it will be available for all children automatically.
BTW, I’m not a fan of the Ambient Context described above because it’s basically a single purpose DI container, and you must have a concrete reference to multiple ambient service containers. If the easy access of this pattern appeals to you, look into Service Location which is the same idea but more flexible.
If ILogger is really a cross-cutting concern, which is used everywhere and thus just causes to pollute every instance with a new constructor parameter, then what you need is to you use a special way of dependency injection called AmbientContext.
Basically it provides you a singleton Context property, which can be accessed from anywhere in the business scope and contains the "global" dependencies such as logging, time service, etc., whatever you need.
But please note that it doesn't mean you can throw out your ILogger and use a static Log class with a hardcoded implementation. Ambient context is also a way of dependency injection so its dependencies should be resolved.
I have a class that encapsulates a bunch of strings that serve as defaults for app settings that haven't been otherwise explicitly specified by the user.
I'm currently using a plain old class with relevantly-named instance methods—this sort of thing:
class SiteConfigurationConventions : ISiteConfigurationConventions
{
public String GetConfigurationFileName()
{
return "SiteConfiguration.xml";
}
}
It seems that a static class would be more conceptually appropriate (like System.Math) since these strings won't ever change at run time and no fields are required, but I'm not sure how compatible static classes are with DI. For example, it doesn't seem possible to register a static class with the container so it returns it to constructors asking for it in other objects being resolved by the container.
As it is now, I register
container.RegisterType<ISiteConfiguration, SiteConfiguration>();
So that the requesting constructor gets what it needs:
public SiteGenerator(ISiteConfiguration siteConfiguration)
My design options would seem to be:
Refactor to a static class and reference the concrete type directly in my consuming class rather than using constructor injection
Leave it as-is (class and instance resolved to an interface), perhaps optionally registering it using the singleton lifetime for the sake of correctness
Creatging some kind of facade or factory to hide the static behind. However, for some reason this options just strikes me as silly.
The notion of an "instance" of a class like this seems odd—static seems more conceptually correct. The only reason I'd be making it an instantiable class is to make it more DI friendly. Does that sound OK, or correct? Am I missing something entirely?
Any counsel would be most appreciated. :)
Most DI libraries give you the option to specify that a single instance can be used for all injections (creates a single instance and give that as the answer every time). This is a form of Singleton, and would probably suit your problem well.
For example, using MS Unity library, you would put:
container.RegisterInstance(new SiteConfiguration());
I consider the static keyword to be a form of built-in singleton implementation, while the DI route does much the same thing, but without using the compiler to take care of the details.
OK, after a bit of research, Googling, and thinking, I believe I've arrived at my own conclusions.
The use of static classes is in a sense at odds with the IoC principle and loose coupling that I intend to bake into my architecture. The static modifier is a way of saying that only one implementation can answer a particular purpose, which is at odds with DI generally (loose coupling, programming to interfaces, testability, and all the things that go with that).
Equally, the static modifier is really just a way of telling the compiler we want to restrict the number of instances of a class to one while simultaneously never allowing it to be assigned to a variable (i.e., no use of the new operator). If we are to employ IoC, we should be leaving lifestyle management like this up to the composition root, and we're never directly referencing concrete classes (other than FCL classes) this way anyway. So static classes serve little purpose to us.
Therefore, I say leave it as a plain old (non-static) class and apply a singleton lifestyle at the composition root. Unless, of course, you think your would-be static class is unlikely ever to change and that you'll never need to fake it in testing, in which case you could just treat it like a stable dependency (like an FCL class) and exclude it from your normal DI scheme, referencing the concrete class directly in consuming classes.
If you must depend on a third-party class that uses static methods or is itself entirely static that you want to inject as a dependency (and thus be able to substitute for testing, etc., purposes), you should perhaps still create an interface and rely on an instantiable adapter that calls the static methods to get those values.
I've started the very long and arduous quest to learn and apply TDD to my workflow. I'm under the impression that TDD fits in very well with IoC principles.
After browsing some of TDD tagged questions here in SO, I read it's a good idea to program against interfaces, not objects.
Can you provide simple code examples of what this is, and how to apply it in real use cases? Simple examples is key for me (and other people wanting to learn) to grasp the concepts.
Consider:
class MyClass
{
//Implementation
public void Foo() {}
}
class SomethingYouWantToTest
{
public bool MyMethod(MyClass c)
{
//Code you want to test
c.Foo();
}
}
Because MyMethod accepts only a MyClass, if you want to replace MyClass with a mock object in order to unit test, you can't. Better is to use an interface:
interface IMyClass
{
void Foo();
}
class MyClass : IMyClass
{
//Implementation
public void Foo() {}
}
class SomethingYouWantToTest
{
public bool MyMethod(IMyClass c)
{
//Code you want to test
c.Foo();
}
}
Now you can test MyMethod, because it uses only an interface, not a particular concrete implementation. Then you can implement that interface to create any kind of mock or fake that you want for test purposes. There are even libraries like Rhino Mocks' Rhino.Mocks.MockRepository.StrictMock<T>(), which take any interface and build you a mock object on the fly.
It's all a matter of intimacy. If you code to an implementation (a realized object) you are in a pretty intimate relationship with that "other" code, as a consumer of it. It means you have to know how to construct it (ie, what dependencies it has, possibly as constructor params, possibly as setters), when to dispose of it, and you probably can't do much without it.
An interface in front of the realized object lets you do a few things -
For one you can/should leverage a factory to construct instances of the object. IOC containers do this very well for you, or you can make your own. With construction duties outside of your responsibility, your code can just assume it is getting what it needs. On the other side of the factory wall, you can either construct real instances, or mock instances of the class. In production you would use real of course, but for testing, you may want to create stubbed or dynamically mocked instances to test various system states without having to run the system.
You don't have to know where the object is. This is useful in distributed systems where the object you want to talk to may or may not be local to your process or even system. If you ever programmed Java RMI or old skool EJB you know the routine of "talking to the interface" that was hiding a proxy that did the remote networking and marshalling duties that your client didn't have to care about. WCF has a similar philosophy of "talk to the interface" and let the system determine how to communicate with the target object/service.
** UPDATE **
There was a request for an example of an IOC Container (Factory). There are many out there for pretty much all platforms, but at their core they work like this:
You initialize the container on your applications startup routine. Some frameworks do this via config files or code or both.
You "Register" the implementations that you want the container to create for you as a factory for the interfaces they implement (eg: register MyServiceImpl for the Service interface). During this registration process there is typically some behavioral policy you can provide such as if a new instance is created each time or a single(ton) instance is used
When the container creates objects for you, it injects any dependencies into those objects as part of the creation process (ie, if your object depends on another interface, an implementation of that interface is in turn provided and so on).
Pseudo-codishly it could look like this:
IocContainer container = new IocContainer();
//Register my impl for the Service Interface, with a Singleton policy
container.RegisterType(Service, ServiceImpl, LifecyclePolicy.SINGLETON);
//Use the container as a factory
Service myService = container.Resolve<Service>();
//Blissfully unaware of the implementation, call the service method.
myService.DoGoodWork();
When programming against an interface you will write code that uses an instance of an interface, not a concrete type. For instance you might use the following pattern, which incorporates constructor injection. Constructor injection and other parts of inversion of control aren't required to be able to program against interfaces, however since you're coming from the TDD and IoC perspective I've wired it up this way to give you some context you're hopefully familiar with.
public class PersonService
{
private readonly IPersonRepository repository;
public PersonService(IPersonRepository repository)
{
this.repository = repository;
}
public IList<Person> PeopleOverEighteen
{
get
{
return (from e in repository.Entities where e.Age > 18 select e).ToList();
}
}
}
The repository object is passed in and is an interface type. The benefit of passing in an interface is the ability to 'swap out' the concrete implementation without changing the usage.
For instance one would assume that at runtime the IoC container will inject a repository that is wired to hit the database. During testing time, you can pass in a mock or stub repository to exercise your PeopleOverEighteen method.
It means think generic. Not specific.
Suppose you have an application that notify the user sending him some message. If you work using an interface IMessage for example
interface IMessage
{
public void Send();
}
you can customize, per user, the way they receive the message. For example somebody want to be notified wih an Email and so your IoC will create an EmailMessage concrete class. Some other wants SMS, and you create an instance of SMSMessage.
In all these case the code for notifying the user will never be changed. Even if you add another concrete class.
The big advantage of programming against interfaces when performing unit testing is that it allows you to isolate a piece of code from any dependencies you want to test separately or simulate during the testing.
An example I've mentioned here before somewhere is the use of an interface to access configuration values. Rather than looking directly at ConfigurationManager you can provide one or more interfaces that let you access config values. Normally you would supply an implementation that reads from the config file but for testing you can use one that just returns test values or throws exceptions or whatever.
Consider also your data access layer. Having your business logic tightly coupled to a particular data access implementation makes it hard to test without having a whole database handy with the data you need. If your data access is hidden behind interfaces you can supply just the data you need for the test.
Using interfaces increases the "surface area" available for testing allowing for finer grained tests that really do test individual units of your code.
Test your code like someone who would use it after reading the documentation. Do not test anything based on knowledge you have because you have written or read the code. You want to make sure that your code behaves as expected.
In the best case you should be able to use your tests as examples, doctests in Python are a good example for this.
If you follow these guidelines changing the implementation shouldn't be an issue.
Also in my experience it is good practice to test each "layer" of your application. You will have atomic units, which in itself have no dependencies and you will have units which depend on other units until you eventually get to the application which in itself is a unit.
You should test each layer, do not rely on the fact that by testing unit A you also test unit B which unit A depends on (the rule applies to inheritance as well.) This, too, should be treated as an implementation detail, even though you might feel as if you are repeating yourself.
Keep in mind that once written tests are unlikely to change while the code they test will change almost definitely.
In practice there is also the problem of IO and the outside world, so you want to use interfaces so that you can create mocks if necessary.
In more dynamic languages this is not that much of an issue, here you can use duck typing, multiple inheritance and mixins to compose test cases. If you start disliking inheritance in general you are probably doing it right.
This screencast explains agile development and TDD in practice for c#.
By coding against an interface means that in your test, you can use a mock object instead of the real object. By using a good mock framework, you can do in your mock object whatever you like.
This may seem obvious to most people, but I'm just trying to confirm that Dependency Injection (DI) relies on the use of Interfaces.
More specifically, in the case of a class which has a certain Interface as a parameter in its constructor or a certain Interface defined as a property (aka. Setter), the DI framework can hand over an instance of a concrete class to satisfy the needs of that Interface in that class. (Apologies if this description is not clear. I'm having trouble describing this properly because the terminology/concepts are still somewhat new to me.)
The reason I ask is that I currently have a class that has a dependency of sorts. Not so much an object dependency, but a URL. The class looks like this [C#]:
using System.Web.Services.Protocols;
public partial class SomeLibraryService : SoapHttpClientProtocol
{
public SomeLibraryService()
{
this.Url = "http://MyDomainName.com:8080/library-service/jse";
}
}
The SoapHttpClientProtocol class has a Public property called Url (which is a plain old "string") and the constructor here initializes it to a hard-coded value.
Could I possibly use a DI framework to inject a different value at construction? I'm thinking not since this.Url isn't any sort of Interface; it's a String.
[Incidentally, the code above was "auto-generated by wsdl", according to the comments in the code I'm working with. So I don't particularly want to change this code, although I don't see myself re-generating it either. So maybe changing this code is fine.]
I could see myself making an alternate constructor that takes a string as a parameter and initializes this.Url that way, but I'm not sure that's the correct approach regarding keeping loosely coupled separation of concerns. (SoC)
Any advice for this situation?
DI really just means a class wont construct it's external dependencies and will not manage the lifetime of those dependencies. Dependencies can be injected either via constructor, or via method parameter. Interfaces or abstract types are common to clarify the contract the consumer expects from its dependency, however simple types can be injected as well in some cases.
For example, a class in a library might call HttpContext.Current internally, which makes arbitrary assumptions about the application the code will be hosted in. An DI version of the library method would expect a HttpContext instance to be injected via parameter, etc.
It's not required to use interfaces -- you could use concrete types or abstract base classes. But many of the advantages of DI (such as being able to change an implementation of a dependancy) come when using interfaces.
Castle Windsor (the DI framework I know best), allows you to map objects in the IoC container to Interfaces, or to just names, which would work in your case.
Dependency Injection is a way of organizing your code. Maybe some of your confusion comes from the fact that there is not one official way to do it. It can be achieved using "regular" c# code , or by using a framework like Castle Windsor. Sometimes (often?) this involves using interfaces. No matter how it is achieved, the big picture goal of DI is usually to make your code easier to test and easier to modify later on.
If you were to inject the URL in your example via a constructor, that could be considered "manual" DI. The Wikipedia article on DI has more examples of manual vs framework DI.
I would like to answer with a focus on using interfaces in .NET applications. Polymorphism in .NET can be achieved through virtual or abstract methods, or interfaces.
In all cases, there is a method signature with no implementation at all or an implementation that can be overridden.
The 'contract' of a function (or even a property) is defined but how the method is implemented, the logical guts of the method can be different at runtime, determined by which subclass is instantiated and passed-in to the method or constructor, or set on a property (the act of 'injection').
The official .NET type design guidelines advocate using abstract base classes over interfaces since they have better options for evolving them after shipping, can include convenience overloads and are better able to self-document and communicate correct usage to implementers.
However, care must be taken not to add any logic. The temptation to do so has burned people in the past so many people use interfaces - many other people use interfaces simply because that's what the programmers sitting around them do.
It's also interesting to point out that while DI itself is rarely over-used, using a framework to perform the injection is quite often over-used to the detriment of increased complexity, a chain-reaction can take place where more and more types are needed in the container even though they are never 'switched'.
IoC frameworks should be used sparingly, usually only when you need to swap out objects at runtime, according to the environment or configuration. This usually means switching major component "seams" in the application such as the repository objects used to abstract your data layer.
For me, the real power of an IoC framework is to switch implementation in places where you have no control over creation. For example, in ASP.NET MVC, the creation of the controller class is performed by the ASP.NET framework, so injecting anything is impossible. The ASP.NET framework has some hooks that IoC frameworks can use to 'get in-between' the creation process and perform their magic.
Luke
Currently I have created a ABCFactory class that has a single method creating ABC objects. Now that I think of it, maybe instead of having a factory, I could just make a static method in my ABC Method. What are the pro's and con's on making this change? Will it not lead to the same? I don't foresee having other classes inherit ABC, but one never knows!
Thanks
Having a single, static method makes this much more difficult to test whereas having an instantiable object allows this to be easier to test. Also, dependency injection is later more of an option with the non-static solution.
Of course, if you don't need any of this, then these are not good arguments.
The main advantage of the factory method is the ability to hide reference to a specific class behind an interface. Since static methods can not be a part of the interface, static factory methods are basically the same as the constructor method itself. The only useful application of the static factory methods is to provide access to a private constructor - what is commonly used for singleton-pattern implementation.
In reality, if you want to get the benefits of a factory class, you need the static method in it's own class. This will allow you to later create new factory classes, or reconfigure the existing one to get different behaviors. For example, one factory class might create Unicorns which implement the IFourHoovedAnimal interface. You might have an algorithm written that does things with IFourHoovedAnimal's and needs to instantiate them. Later you can create a new factory class that instead instantiates Pegasus's which also implement IFourHoovedAnimal's. The old algorithm can now be reused for Pegasus's just by using the new factory! To make this work both the PegasusFactory and the UnicornFactory must inherit from some common base class(usually an abstract class).
So you see by placing the static method in it's own factory class, you can swap out factory classes with newer ones to reuse old algorithms. This also works for improving testability, because now unit tests can be fed a factory that creates mock objects.
I have done the latter before (static factory method on the class that you are creating instances of) for very small projects, but it was only because I needed it to help refactor some old code, but keep changes to a minimum. Basically in that case I had factored out a chunk of code that created a bunch of ASP.NET controls, and stuff all those controls into a user control. I wanted to make my new user control property based, but it was easier for the old legacy code to create the user control with a parameter based constructor.
So I created a static factory method that took all the parameters, and then instanced the user control and set it's properties based on the parameters. The old legacy code used this static method to create the user control, and future code would use the "prettier" properties instead.
For concrete classes, factory methods are really just a method of indirection around creating the actual type (which isn't to say they aren't useful, but as you've found, the factory method could really be anywhere).
Where the factory method really shines though is when your method creates instances of an interface type.
The "D" in Uncle Bob's SOLID Principles of Object Oriented Design is "The Dependency Inversion Priciple" Depend on abstractions, not on concretions.
An extreme following of that principle could have your main class create all your factories, with each factory using other factories via interfaces. The only appearance of "new" (creating concrete objects) would be in your main class, and your factories. All your objects would work with interfaces (abstractions), with the concrete dependencies obtained from supplied factory implementations.
You could then very easily adjust, or provide multiple Main classes customised for different scenarios.
Overuse of design patterns are dangerous, and creational design patterns make sense when you have class hierarchies with defined interfaces, or need to build rather complex objects. If you have a simple design, use simple solutions. Therefore, in your case, Factory Method would be enough
Yes, you are right, it is another design pattern :)