Search code examples
c#.net-coredependency-injectionabstract-class

Dependency injection with abstract class in .NET Core


I don't know how to use a dependency injection in an abstract class. Let me show you my problem in a simple example:

public abstract class Animal {

    public abstract void Move();

    public void Sleep() 
    {
        restService.StartSleeping(1000);    //how to get this service here?
    }
}

public class Cat : Animal
{
    public readonly IMotionService _motionService;    

    public Cat(IMotionService motionService)
    {
       _motionService = motionService;
    }

    public override void Move()
    {
        _motionService.Run();
    }
}

public class Bird : Animal
{
    public readonly IMotionService _motionService;    

    public Bird(IMotionService motionService)
    {
       _motionService = motionService;
    }

    public override void Move()
    {
        _motionService.Fly();
    }
}

Every animal move in different way so the Move() function is implemented separately in every derived class. As you probably noticed the whole implementation comes from the motionService. On the other hand all animals sleep in same way, so I want put the Sleep() implementation in a base abstract class to avoid a duplication code, but I can't use my restService with a Sleep implementation because I don't have idea how to inject a service class into an abstract class.

I thought about IServiceProvider but it should be injected too.


Solution

  • You pass it down like this:

    public abstract class Animal 
    {
        private readonly IRestService restService;
    
        public Animal( IRestService restService )
        {
            this.restService = restService;
        }
    
        public abstract void Move();
    
        public void Sleep() 
        {
            restService.StartSleeping(1000);
        }
    }
    
    public class Cat : Animal
    {
        // vv Should be private!
        public readonly IMotionService _motionService;    
    
        public Cat(IMotionService motionService, 
                   IRestService restService)
                : base(restService) // pass on to base class ctor
        {
           _motionService = motionService;
        }
    
        public override void Move()
        {
            _motionService.Run();
        }
    }
    
    // Same in `Bird` class
    

    For reference: Using Constructors (C# Programming Guide)