I am struggling for last two days to get a grip of DI.
I have two problems:
If I have a some common functionality why I can't do the same thing implementing DI with an abstract class?
In my example I have many class instance created under writefile, so should I move out all object creation from there? What if I have a layered design? Should these classes be passed all along?
public interface IWriteFile
{
void write();
}
public class WriteXMLFile : IWriteFile
{
public void write()
{
}
}
public class writefile
{
IWriteFile _file;
public writefile(IWriteFile file)
{
_file = file;
}
public void WriteMyFile()
{
_file.write();
}
}
Regarding your first point:
Let's say you want to test something that uses your abstract class. If you're directly using an abstract class, then if you want to do something different in the shared functionality in the common class, there's not much you can do.
With an interface, you've broken the coupling with the dependency. This is what the Dependency Inversion Principle in SOLID is talking about when it says "High-level modules should not depend on low-level modules. Both should depend on abstractions". Your class shouldn't depend on the lower-level class (even if it's an abstract class) to get its work done. Both the lower-level and higher-level class should depend on the interface which defines how they are going to interact. Using an interface helps separate the two, giving you loose coupling. Something else can handle wiring them together.
Regarding your second point:
Powerful DI frameworks actually handle a lot of this complexity for you.
Let's say you have a class - Thing - that has a bunch of dependencies.
public Thing(
IThingRepository repository,
IEmailer emailer,
ILogger logger,
INeedMoreStuff stuff
) : IThing
When you set up your IoC container, you'd do something like the following to associate which implementation to use for each interface:
IoC.Register<MySqlThingRepository>().As<IThingRepository>();
IoC.Register<MicrosoftExchangeEmailer>().As<IEmailer>();
IoC.Register<TruncatingFileLogger>().As<ILogger>();
IoC.Register<MoreStuff>().As<INeedMoreStuff>();
IoC.Register<Thing>().As<IThing>();
Then you can simply do:
IThing thing = IoC.Resolve<IThing>();
These fancy frameworks handle getting all the dependencies for you (since you told it how to get them) and will construct a Thing for you.
That being said, sometimes a fancy framework like that is overkill. In those cases, I usually use the factory pattern to abstract out the details of creating an object while still making sure the object being created follows good DI principles like constructor injection of its dependencies.
Regarding your polymorphism and interfaces:
Someone described polymorphism as simply "Same interface, different implementation. Substitutability". Wikipedia defines it as "the provision of a single interface to entities of different types". According to those definitions, I think using interfaces doesn't go against polymorphism. I feel in C# interfaces are usually sufficient for providing different implementations of the same "interface".
Yes, you can use an abstract base class to do the same thing, but I'd only use that if there's a common set of functionality I can factor out into the base class to keep my code DRY.
Regarding multiple implementations for an interface with StructureMap
I don't how StructureMap handles this, but presumably there's some logic that will decide when you want to use Thing1 versus Things2. You might be able to provide a delegate to StructureMap that it can use to get an IThing which would contain that logic.
Alternatively, you can have a factory that takes some parameters and decides which IThing to return. There are situations where I've put an interface on my factory and constructor injected that, or alternatively have the factory creating the object using IThing use the ThingFactory to get the right one.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
When you create an interface and you know you will have a dependency on another, do you make the constructor part of the interface?
In my case, I want to create
An IClientReceiveRecorder that I can give to a client and have all the network traffic collected for a short test session. It is probably just going to contain a collection of strings.
An IEvaluator that can get all the messages received and implement various things we want to test for. For example, I might have a concrete Evaluator that tests whether or not all the strings contain the letter 'c'.
I know that any IEvaluator is going to need a IClientReceiveRecorder to get the messages it is to evaluate.
So, I see a few options.
Do I do something like
interface IEvaluator
{
IEvaluator(IClientReceiveRecorder);
void Evaluate();
}
It doesn't compile, so I am guessing not.
Perhaps I do something like
interface IEvaluator
{
void Evaluate(IClientReceiveRecorder);
}
Or, do I just leave it up to the concrete class to take a IClientReceiveRecorder in its constuctor?
The straight forward answer is to leave implementation detail up to the concrete class.
Knowing that the implementation of IEvaluator is going to have a dependency of IClientReceiveRecorder is an implementation detail and would not be included in the IEvaluator interface.
If you know that the interface is going to be composed of another interface you could do something like the following:
interface IEvaluator
{
IClientReceiveRecorder { get; set; }
void Evaluate();
}
How that property is populated is an implementation detail and should not be part of the interface.
You really shouldn't need to.
An interface isn't necessarily a contract of dependencies, it's a contract of functionality. Any implementation can expose its dependencies via constructor(s). But in the event that a different implementation has different (or no) dependencies, it still implements the interface and exposes the functionality.
One thing you could do is expose a property getter in the interface which shows the dependency. This would at least imply to implementing types that they need to expose a getter with the intended type, which happens to be a dependency.
Another alternative entirely might be to use an abstract class instead of an interface. (Understanding the differences between them, of course.) That abstract class can also use a constructor to expose the dependency, and implementing types would have to use that constructor. This alternative could necessitate other changes throughout your code, so it's up to you.
I would leave any mention of the IClientReceiveRecorder out of the interface. As others have mentioned it's an implementation detail.
Further to this point, you do not know of any further uses you may have for the IEvaluator interface. If you keep the interface as follows:
public IEvaluator
{
void Evaluate();
}
then this is a very flexible interface that can be reused for any class that wants to implement evaluation semantics in future. This ties in with the Interface Segregation Principle and Single Responsibility Principle and helps to keep your classes decoupled.
Therefore, instead of including the IClientReceiveRecorder in the IEvaluateinterface simply pass it via the constructor:
public ConcreteEvaluator : IEvaluate
{
private readonly IClientReceiveRecorder recorder;
public ConcreteEvaluator(IClientReceiveRecorder recorder)
{
this.recorder = recorder;
}
public void Evaluate()
{
this.recorder.DoSomeRecording();
}
}
Interfaces don't have constructors, as you've already discovered. That's because the point of using an interface is to have your class interact with contracts for other classes, not actual implementations. That interaction is defined in the interface, but how the actual implementation gets created is not part of that interface. Ideally a class should not know how the abstractions it depends on get created.
That's a reason why constructor injection is helpful for keeping classes decoupled.
If I do this, which is a very common pattern:
public class ClassThatDependsOnSomething
{
private readonly IDependsOnThis _dependsOnThis;
public ClassThatDependsOnSomething(IDependsOnThis dependsOnThis)
{
_dependsOnThis = dependsOnThis;
}
}
then the class interacts with the interface it depends on without being responsible for creating it - calling its constructor. That keeps it truly decoupled. If my class calls the constructor, that means it knows the difference between one implementation that has one constructor vs. another implementation with a different constructor. At that point it's coupled to the implementation.
Also, what if the implementation of IDependsOnThis has its own dependencies? If ClassThatDependsOnSomething calls the implementations's constructor and passes in those dependencies, where will get those from? It would have to create them too.
This is why we use dependency injection containers. To oversimplify, a DI container allows us to declare what all of the implementations will be for all of the interfaces we use. Then we can ask the container to resolve an implementation of an interface. If that implementation has a constructor that requires more interfaces, it resolves those. And so on, and on. So when working with one class, you only need to be concerned with the that one class and the interfaces it depends on, but you shouldn't have to think about the details of the implementations of those interfaces.
One of the key benefits of this is that since a class depends on interfaces passed into its constructor, you can write unit tests for the class and pass in "mocks" or "test doubles," really simple classes that implement the interfaces and provide dummy responses to method calls. By controlling exactly what all of the dependencies do, you can test that your class behaves exactly as expected.
If have two classes Class1 and Class2 both implementing an interface IInterface.
And now, if I need a singleton instance of each of these classes, would this be the right way to implement it?
c.ForSingletonOf<IInterface>().Use<Class1>().Named("Class1");
c.ForSingletonOf<IInterface>().Add<Class2>().Named("Class2");
And then getting the instances like this:
container.GetInstance<IInterface>("Class1");
container.GetInstance<IInterface>("Class2");
Is there anything wrong in this approach or is there a better approach?
If you want access to a specific implementation of IInterface you will need access to the container in order to request the specific named instance.
Constructor injection will always provide you with Class1 as that is what you have told structuremap to use for IInterface. So this will probably lead you to pass the container around which is a very bad idea.
If the objects need to be created as singletons, I would suggest not injecting as IInterface but as Class1 and Class2. They are first class citizens in your application and qualify for direct access.
c.ForSingletonOf<Class1>().Use<Class1>();
c.ForSingletonOf<Class2>().Use<Class2>();
Depending on what blogs you read, you may want to specify the implementation of Class1 and Class2 as interfaces attributing to what purpose they provide. This way you future proof them if the backing singleton of IClass1 or IClass2 should change.
public interface IClass1 : IInterface { }
public interface IClass2 : IInterface { }
-----
c.ForSingletonOf<IClass1>().Use<Class1>();
c.ForSingletonOf<IClass2>().Use<Class2>();
That is how I would go about it. Named instances in the container I have found are only useful when configuring the container as I have access to it. When it comes to dependency injection they are not useful as the named instance you require is specified by the class/interface name. If you require more than one implementation of the same interface, they qualify for their own interface imo
I have a simple interface defined
public interface IBla
{
public void DoThing();
public void DoAnotherThing();
public void Thing();
}
I have a bunch of classes which implement this interface. Lots of them however only need two of the three functions which that interface implements, so currently I implement the remaining ones as well and just leave them empty like so:
public void DoThing(){}
Is there some more elegant way of doing this?
I do NOT want to have multiple interfaces defined for this.
Is there perhaps something like a "partialInterface" where I don't have to implement all of the functions from that interface into a class which implements that interface?
Thanks
When implementing an interface, the type that implements the interface must provide an implementation for everything that interface details.
There is no support for partial interfaces or anything similar to what you want, other than breaking up the interface.
You're basically asking "How can I implement the calculator interface without requiring me to provide the + operator" and in short, you can't. It would no longer be a calculator according to that interface.
The closest thing you get is that you can create a base class that provides default implementations for the whole interface or parts of it, and inherit from this base type, so that inherited classes become easier to implement with less code, but they will provide the entire interface.
I know you said you don't want separate interfaces, but for the benefit of others in future who want the right answer to this question here it is:
What you describe is the point at which you separate your interfaces out, and use interface inheritance.
public interface IBasic
{
void DoThing();
}
public interface IAdvanced : IBasic
{
void DoAnotherThing();
void Thing();
}
Implementations which only need DoThing only implement IBasic. Implementations which need all functionality implement IAdvanced which includes the method from IBasic plus the additional functionality.
If you have classes which implement not all methods, then you probably need to separate this interface into smaller interfaces.
Many specific interfaces are better than one universal.
Creating the classes which implement your interface, and throw NotImplementedException or simply do nothing looks like SOLID rules violation.
Well, it is highly discouraged to only partially implement an interface, there is a way to sort of do it.
Most answers talk about breaking up your interface into multiple interfaces, which makes sense. But, if this is not possible simply implement the members that you do not want to use in an explicit manner, and if they get called you should throw a NotSupportedException.
If you want to see an example of this in use, look no further than Microsoft's own code: http://referencesource.microsoft.com/#mscorlib/system/collections/objectmodel/readonlycollection.cs
void ICollection<T>.Add(T value)
{
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
Given that these things are being processed in a game loop, presumably implementations of IBla are things like the player character, enemies, obstacles, missiles and the like and DoThing etc and Move, Fire and so forth.
If so, then your approach is perfectly valid. An immobile object should have a Move method (so the game loop can call it), and since it can't move, an empty method is a valid implementation.
If you control both interfaces then separate the interfaces into multiple interfaces. As suggested, one interface can inherit from the other, or you could just have some classes implement both interfaces.
In this case interface inheritance is probably the better choice because you won't have to modify the classes that already implement the larger interface.
What if the larger interface is one you don't control, so splitting it into multiple interfaces isn't an option? It's not a good idea to implement the interface and leave some methods without implementations. If a class implements an interface then it should really implement the interface.
A solution is to define the smaller interface that you actually want and create a class that adapts the larger interface to your smaller one.
Suppose you have this interface
public interface IDoesFourThings
{
void DoThingOne();
void DoThingTwo();
void DoThingThree();
void DoThingFour();
}
And you want a class that only implements two of those things? You shouldn't implement IDoesFourThings if the class really only does two things.
So first, create your own interface:
public interface IDoesTwoThings
{
void DoThingA();
void DoThingB();
}
Then create a class that adapts an implementation of IDoesFourThings to your interface.
public class DoesTwoThingsUsingClassThatDoesFourThings : IDoesTwoThings
{
private readonly IDoesFourThings _doesFourThings;
public DoesTwoThingsUsingClassThatDoesFourThings(IDoesFourThings doesFourThings)
{
_doesFourThings = doesFourThings;
}
public void DoThingA()
{
_doesFourThings.DoThingTwo();
}
public void DoThingB()
{
_doesFourThings.DoThingThree();
}
}
Just for the sake of example I avoided naming the methods in IDoesTwoThings to match the ones in IDoesFourThings. Unless they're really exactly the same thing then the new interface doesn't need to match the old one. It is its own interface. That the class works by using an inner implementation of IDoesFourThings is hidden.
This relates to the Interface Segregation Principle, the I in SOLID. One way of thinking about it is this: An interface describes what a class does, but from the perspective of the client class it should describe what the client needs. In this case the client needs two things, not four.
This approach can be very helpful because it enables us to work on one class at a time and defer the implementation of other details. If we're writing a class and we realize that it's going to require a dependency that does two things, we can just write the interface for those two things and make our class depend on it. (Now that class is more testable because it depends on an interface which we can mock.) Then, whatever that new interface is that we just created, we can also create an implementation for that.
It's a great way to manage the complexity of writing code and avoid getting stuck because now we can just work on our one class with its single responsibility, not worrying too much about how the next class and the next one will work. (We likely have an idea how they will work, but maybe we don't. Either way it doesn't slow us down.)
I know that this question might be asked for many times in this website. I have read the other posts and read some books about why we have to use interfaces. All those posts and books say that, interfaces are like classes but they can only contain functions and all the classes that implement them should also implement their methods.
So I basically know what they are but I don't understand why should I write an interface at all, when I can make a superclass and extend the my other classes to that superclass without rewriting inherited functions again and again.
I would really appreciate if someone explains that to me please.
The key point of using interfaces is to create loosely coupled types. This is because interfaces are completely abstract and each class that implements them should have its own particular implementation of the interface’s methods.
If you create a base class instead of an interface, all the derived classes are tightly coupled with the base class. In particular situations, this tight coupling can cause some problems. The simplest and the most digestible problem that this tight coupling can cause is to create statically bound behaviors which can limit the code to a particular context. On the other hand loosely coupled types are dynamically bound which means they are more general and more reusable.
For example: imagine that you have one class named Service and another named Customer, if you do:
class Service {
public void RenderService() {…}
…
}
class Customer: Service {
public Customer () {…}
…
}
The Customer class in this example in tightly coupled with the Service class. Imagine if we want to introduce a new Service called Service2. Now, our Customer class will become useless and we need to also introduce another class like Customer2.
Now imagine the use of an interface:
interface IService {
void RenderService();
}
class Service: IService {
public void RenderService() {…}
}
class Customer {
IService service;
public Customer(IService service) {
this.service = service;
}
}
Using this technique (also known as Dependency Injection) you can introduce Service2 by creating another class which also implements the IService interface and still keep your Customer class useful and prevent the need to rewrite it.
Apart from this, there are other reasons to use interfaces such creating highly general (i.e. polymorphic) types or methods. So, as a conclusion, there’s a huge difference between simply writing classes and using inheritance and introducing an interface to your code. I hope I could help you digest the use of interfaces.
I am beginning my journey of learning about dependency injection, and one of the reasons that I saw why it is a good idea to use DI was that it explicitly specifies your dependencies, which also makes your code more clear.
I have also noticed that interfaces are used abundantly, but I want to know why would we not use abstract classes for the sole purpose of specifying a default constructor?
Of course no implementation could be included in the abstract class.
Wouldn't this:
abstract class FooBase
{
protected IBar _bar;
FooBase(IBar bar)
{
_bar = bar;
}
abstract void DoSomething();
abstract void DoSomethingElse();
}
Demonstrate more clearly what the dependency of a FooBase object is more than:
interface IFoo
{
IBar Bar { get; }
void DoSomething();
void DoSomethingElse();
}
?
Please keep in mind I am new to this whole concept so be nice :)
One technical reason - forcing particular parent class in languages without multiple inheritance (Java/C#) will significantly restrict freedom of implementation of the "interface".
Note that there are 2 concepts hidden behind "interface" word and it sort of make it harder to reason in C#:
"interface" and abstract concept: well defined set of properties/methods to interact with an object; contract to work with an object.
"interface" as type in particular language (C#/Java) - one possible representation of
contract in given language.
Abstract/concrete classes can be used to represent contract, but force restrictions on implementers of contract in C#.
Some other languages (like C++) don't have such restriction and abstract classes is good option there. Other languages (i.e. "duck-types" JavaScript) does not have such class/interface distinction, but you can still have "contract" with an object.
Sample:
To provide more context where you should be hitting this restriction yourself in C#: DI is commonly used along with some form of TDD or at least with basic unit tests. So you try write some code and tests that uses abstract base class for DI.
abstract class Duck {
abstract void Quack();
}
class ConcreteDuck : Duck {...}
Now if you decide to write tests you may already have test classes that helps you to mock objects (if you are not using existing once)
class MockBase {...}
class MockDuck : MockBase,?????? // Can't use Duck and MockBase together...
Interface defines a contract. An Abstract base class defines a behavior.
Essentially, you can provide a single class that implements multiple interfaces,
which then in turn can be injected into multiple classes, but you will only have
a single abstract base class (at least in C#).
Consider the point of registering a type at the container (the composition root at best)
and consider the point where you resolve the dependency (the constructor or a property).
This SO will cover some more aspects SO on interface vs base class
In .NET, you only have single inheritance. In languages/frameworks where this is the case, opting to use an abstract class as your abstraction gives the potential to "burn the base class".
This means that you force the implementer of your abstraction to inherit from a singular class, when forcing them to do so might result in inconveniencing them severely, depending on what the implementation is.
Let's say that you have your abstract class Contract. If someone has their own Base class that they want to use which exposes only protected methods (for inheritors).
Because the methods are protected, one can't use encapsulation (an instance of Base stored in a field) to access the methods in Base for your abstraction implementation.
Even worse, if you don't have access to modify Base, then you might have to resort to some very ugly workarounds (Reflection, namely).
That said, with interfaces, you give the implementer the choice of where to inherit from and don't limit their options.
The typical pattern you'll see is that you always provide an interface for your contract and code your consumers against the interface. You also provide an abstract base class that provides functionality that people may derive from for convenience, but are not obligated to derive from.
Also, if it's possible for you to provide this functionality in the form of something that is easily encapsulated (for the condition I describe above), it would be even more optimal (you'd have an abstract class which just calls the instance that exposes the methods).