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.
I am using an abstract class but for the second part of my code, I use an Interface.
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();
}
}
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?
Abstract classes should be used primarily for objects that are closely related, whereas interfaces are best suited for providing common functionality to unrelated classes. If you are designing small, concise bits of functionality, use interfaces. If you are designing large functional units, use an abstract 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. Save this answer.
You can skip the interface role and inject the service object directly into the client. But by doing that, you break with the dependency inversion principle and your client has an explicit dependency on the service class. In some situations, this might be ok.
An interface is better than a abstract class when you want multiple classes to implement that interface and when you don't have to inherit default behavior.
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:
public interface IMessage
{
void Get(); // modifiers like public are not allowed here
void Send();
}
And here is your dependent class, which should depend only on abstraction (i.e. interface):
public class MessageManager
{
private IMessage _message;
// depend only on abstraction
// no references to interface implementations should be here
public IMessage Message
{
get { return _message; }
set { _message = value; }
}
public MessageManager(IMessage message)
{
_message = message;
}
}
Then create class, which will implement your interface:
public class Sms : IMessage
{
// do not use explicit implementation
// unless you need to have methods with same signature
// or you want to hide interface implementation
public void Get()
{
Console.WriteLine("Message Get!");
}
public void Send()
{
Console.WriteLine("Message Send!");
}
}
Now you have inversed dependencies - MessageManager
and Sms
depend only on IMessage
. You can inject any IMessage
implementations to MessageManager
(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 original IMessage
interface.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With