0
public class BaseController : Controller
{
    [Inject]
    public IUnitOfWork UnitOfWork { get; set; }
    private readonly ISomeService _someService ;

    public BaseController(ISomeService someService)
    {
        _someService = someService;
    }

    public void Contacts()
    {
        contacts = _someService .GetById(1);
        ViewBag.someThing = contacts; //Add whatever
    }

    public BaseController()
    {

    }
}

While I'm sending someService in the :base I can get the data from it. However I don't want to send someService from each controller like AboutController to the BaseController and to write too much code.

public class HomeController : BaseController
{

    private readonly ISomeService someService;

    public HomeController(ISomeService someService) : base(someService)
    {
        _someService = someService;
    }
}

public class AboutController : BaseController
{
    private readonly IAboutService _aboutService;
    public AboutController (IAboutService aboutService) 
    {
        _aboutService = aboutService;
    }
}

So in AboutController view still i wanna get someService's data without sending parameter to the BaseController

kayess
  • 3,384
  • 9
  • 28
  • 45
Maho
  • 35
  • 1
  • 6

1 Answers1

1

The short answer would be separated in two cases:

  1. If you want to use ISomeService from the base controller you are obliged to pass that service through base constructor like this:

    public class AboutController : BaseController
    {
         private readonly IAboutService _aboutService;
         public AboutController (IAboutService aboutService, ISomeService someService)  : base(someService)
         {
             _aboutService = aboutService;
         }
    }
    
  2. If you dont want to use that service you use the default base constructor like this otherwise it will be null if you try to access it:

    public class AboutController : BaseController
    {
       private readonly IAboutService _aboutService;
       public AboutController (IAboutService aboutService)  : base()
       {
           _aboutService = aboutService;
        }
    }
    

You are in the first scenario so you need to pass it through the constructor in order to initialize it!

But if you like to break the pattern you would choose other ways of injecting the services into your base controller:

First one by using auto-properties:

For example:

public ISomeService SomeService { get; set;}

Another way is to get the instance of the service by using DependecyResolver but this would 'break' somehow the DI pattern and it will make harder for testing etc. But if you choose to do so here is the code for that:

  public class BaseController : Controller
  {
     [Inject]
     public IUnitOfWork UnitOfWork { get; set; }
     private readonly ISomeService _someService ;

     public BaseController(ISomeService someService)
     {
         _someService = someService;
     }

     public void Contacts()
     {
         contacts = _someService .GetById(1);
         ViewBag.someThing = contacts; //Add whatever
     }

     public BaseController()
     {
          _someService = DependencyResolver.Current.GetService<ISomeService >();
     }
}

For more info refer to this question here

Rey
  • 3,663
  • 3
  • 32
  • 55
  • Thank you so much I've done it with DependecyResolver and it works for me now. But still i didn't get the part of bracking the DI pattren.I choose the DependencyResolver in order to decrease the code ,because i'll have too many controllers so I won't send the Someservice as a parameter from each controller. – Maho Sep 15 '17 at 07:03
  • Often it is considered as anti-pattern in DI but in your case I think is the best option. If you think this is a correct answer please consider marking it as such. Thanks :) – Rey Sep 15 '17 at 16:14