Reputation: 1572
I'm learning ASP.NET Core 2
and a question came to my mind. How does Interface
instance gives difference implementations?
Lets get IServiceCollection
. It has various methods like AddMvc(), AddDbContext<T>()
etc. Checking the source code IServiceCollection
doesn't have any methods that has to be implemented if someone implements it. It simply inherits IList<ServiceDescriptor>
and the inheritance chain of IList < ICollection < IEnumerable
Ok, went to see ServiceDescriptor
but the class doesn't implement any interface
and in it there is no method implementations like AddMvc(), AddDbContext<T>
Then how and from where do these methods come from ? How it works behind the scenes?
I'm really trying to learn OOP, but I think I miss some basics.
Upvotes: 1
Views: 328
Reputation:
The trick here is that interfaces can have extra methods tacked on. In C# we do this using extension methods. Here is a basic example:
public interface IFoo
{
int GetFoo();
}
public class Foo : IFoo
{
public int GetFoo()
{
var foo = ... // does something to get a foo
return foo;
}
}
public class Program
{
public static void Main()
{
IFoo theFoo = new Foo();
theFoo.PityTheFoo(); // wait, what?
}
}
Now at this point I can hear you saying "Amy! Hold on! IFoo
doesn't have a method that does any kind of pitying!" And you would be right. Pretend for a moment that you don't own the source code for IFoo
. How can you add a method to IFoo
? Or, suppose you do own the source for IFoo
, and want to add a method without having to modify every class that implements that interface?
This is where extension methods come in:
public static class FooExtensions
{
public static void PityTheFoo(this IFoo foo)
{
// pities the foo
}
}
Note the this
keyword inside the function declaration. That indicates this is an extension method. It tacks our PityTheFoo
method onto the interface. Classes that implement the IFoo
interface do not need to implement PityTheFoo()
. If you had one hundred different Foo
classes, all implementing this interface, none of them will require modification.
Extension methods aren't part of the inheritance chain. When the compiler reaches the commented line in Program
, this is what it "pretends" the code looks like:
public class Program
{
public static void Main()
{
IFoo theFoo = new Foo();
FooExtensions.PityTheFoo(theFoo);
}
}
Why would we want this?
Upvotes: 2
Reputation: 155588
AddMvc()
, AddDbContext()
etc are Extension Methods: a different syntax for invoking a static
function defined in a totally different class that has the System.Runtime.CompilerServices.ExtensionAttribute
(aka [Extension]
) applied to it (in C#, an extension method can be written by putting the this
modifier before the first parameter.
If you use the "Go to definition" feature in VS for those methods you'll see they're defined on Microsoft.Extensions.DependencyInjection.MvcServiceCollectionExtensions.AddMvc
: https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.mvcservicecollectionextensions.addmvc?view=aspnetcore-2.0
Upvotes: 0