I have been reading some articles about the SOLID principles and dependency Inversion. From my point of view, I must use an interface to talk to any class. My classes are chatting by using interfaces.
First Question:
I am using an abstract class but for the second part of my code, I use an Interface.
Usage1
namespace DependencyInjection
{
public interface IMessage
{
}
public abstract class Message
{
public abstract void Get();
public abstract void Send();
}
public class Sms : Message, IMessage
{
public override void Get()
{
Console.WriteLine("Message Get!");
}
public override void Send()
{
Console.WriteLine("Message Send!");
}
}
public class MessageManager
{
private IMessage _message;
public Sms Sms
{
get { return _message as Sms; }
set { _message = value; }
}
public MessageManager(IMessage message)
{
_message = message;
}
}
}
Usage:
class Program
{
static void Main(string[] args)
{
MessageManager msg = new MessageManager(new Sms());
msg.Sms.Get();
msg.Sms.Send();
Console.Read();
}
}
Usage2
namespace DependencyInjection
{
public interface IMessage
{
public void Get();
public void Send();
}
public class Sms : IMessage
{
public void IMessage.Get()
{
Console.WriteLine("Message Get!");
}
public void IMessage.Send()
{
Console.WriteLine("Message Send!");
}
}
public class MessageManager
{
private IMessage _message;
public Sms Sms
{
get { return _message as Sms; }
set { _message = value; }
}
public MessageManager(IMessage message)
{
_message = message;
}
}
}
What is the difference between Usage1 and usage2? When do I choose usage1 or Usage2?
I don't have a lot to add to the other answers provided, apart from some reasons to listen to them:
An abstract class with only abstract methods is essentially an interface. The difference is that it could have some form of virtual implementation, and therein lies the trap: its all too easy when trying to reduce duplication using a base class to hide dependencies.
Let's say you have a set of objects which need to persist between runs. It's tempting to add a save functionality to the base class so that no one else has to worry about how the save works. The problem is, if you totally hide it, you create a testing nightmare where the implementation has to be tested, or else a lot of functionality is relegated to only integration testing. Using Strategy for the save functionality would totally resolve the issue, and the two can be combined simply enough.
The problem is more temptation than one simply being bad. Inheritance does not stop DI, but it doesn't encourage it either. If you're trying to get into SOLID and DI, you may be better off avoiding inheritance for now.
based on what I see you aren't really using an interface at all. Sure you implement the methods, but the consuming class shouldn't really know or even care about the implementation. Therefore, you shouldn't really see any reference or casting to Sms. You should be using a IoC framework such as Unity, Ninject, structuremap. If you actually need a public property returning an IMessage, it should return IMessage and not Sms, whether you should be doing that is a different conversation.
That said, the first Usage doesn't have anything in the IMessage so it is worthless. Also, I often use an abstract / base class to handle common functionality between multiple implementations of an interface. In you scenario, there is no need for the abstract class. The only time I create abstract methods without any code is if the abstract class actually fires that method in some capacity but expects the derived class to implement the functionality.
Anyway, to answer you question Usage #2 seems closer to the correct solution, but just remove the references to Sms and let an IoC container handle that.
An interface does not contain any implementation code and does not force the implementer to derive its implementation form a given class. A base class (abstract or not) can already contain some logic. This can be an advantage as well as an undesirable constraint.
Of course you can combine both approaches. Define and program against an interface and at the same time provide a base class (or several base classes) implementing this interface and proving some basic logic that simplifies an implementers task. A person implementing the interface can decide to go the easy way and to extend a base class or to create something completely new and implement the interface directly.
The .NET Framework class library provides base classes for collections like
Collection<T>
orKeyedCollection<TKey,TItem>
both implementingIList<T>
that you can use as a base for creating your own specialized collection. But of course you can start from scratch and implementIList<T>
directly.The original definition of an interface is an abstract class with all pure virtual methods (i.e. abstract methods), this was how you describe an interface in C++. If you are not creating virtual functions with default definitions then you really do not need an abstract class at all. If you do have some default functionality that you would like the children of your Message class to inherit (and allow to override or not) then you would use an abstract class. An abstract class can also define protected methods and/or properties and fields, these can be used by classes that inherit from the abstract class but not by classes that use the abstract class. All methods in an interface would be public. In the case you laid out an interface would be fine.
The reason to choose an abstract class over an interface has to do with reusable code. The fact that you're using dependency injection doesn't change this answer.
Do all of the subclasses have common functionality? If so, it can be defined in the base class.
Should the template method design pattern be used? If so, the algorithm exists in the base class.
As always, the answer is: "It depends." You can't do these approaches with interfaces as interfaces only specify the contract and don't have implementation. If the contract is all you need, then go with an interface. If you need code to be shared by the subclasses, then go with an abstract class.
Abstract classes here to fight with duplicated code. Interfaces - to define contracts (API).
Depend on interfaces - they simply describe contract (API) of dependency, and they can by mocked easily. So, start with interface:
And here is your dependent class, which should depend only on abstraction (i.e. interface):
Then create class, which will implement your interface:
Now you have inversed dependencies -
MessageManager
andSms
depend only onIMessage
. You can inject anyIMessage
implementations toMessageManager
(MessageManager now fit OCP - open for extension, but closed for modification).Create base abstract message class only when you have duplicated code in several
IMessage
implementors. When you create abstract class (place, where you move duplicated code), you should not change interface, because contract stays the same. Just inherit your base class from originalIMessage
interface.