ASP.NET MultiLayer App Migration To ASP.NET Core

277 views Asked by At

I migrate my ASP.NET multi layer project to ASP.NET Core. I was using Ninject for DI in my old project and i could call it as follow in my BLL.

public void  IamMethodInBll()
{
    ...
    //i could call ninject like this.
    var prodCalcManager = Const.NinjectKernel.Get<IProdCalcService>();
    prodSurr.CalculatedPrice = prodCalcManager.GetMyMethod()
    ..
}

In now i use ASP Net Core's DI system of course. But how can i call the service locator in business layer for ASP.NET core? I need your samples and suggestions.

In Startup.cs

services.AddScoped<IProdCalcService,ProdCalcManager>();

In BLL

public void  IamMethodInBll()
{
    ...
    //What's the proper way to call another service in BLL
    //How can  i get the service provider in BLL
    var prodCalcManager = _serviceProvider.GetService<IProdCalcService>();
    prodSurr.CalculatedPrice = prodCalcManager.GetMyMethod()
    ..
}
2

There are 2 answers

0
Robert Perry On BEST ANSWER

The correct answer is: Dont use ServiceLocator. Register your services using the services.AddScoped<T> like you are and then add that to the constructor of the class you want to use it in.

Like so:

services.AddScoped<IProdCalcService,ProdCalcManager>();

Then your class looks like this:

public class MyClass()
{

    private IProdCalcService calcService;

    public MyClass(IProdCalcService calcService)
    {
        this.calcService = calcService;
    }

    public void IamMethodInBll()
    {

        //...

        prodSurr.CalculatedPrice = calcService.GetMyMethod();

        //...
    }
}
2
Saeid Babaei On

It is better to DONT USE Service Locator but in this case you can inject ServiceProvider to your Controller or better solution is wrap and abstract ServiceProvider in a Container that can be injectable simply. I prefer to use 3rd party DI Containers for use in this situation, specially CastleCore can be good choice.

public interface IContainer 
{
   T Resolve<T>();
}

public class ServiceProviderContainer : IContainer 
{
  private IServiceProvider _serviceProvider; 
  public ServiceProviderContainer(IServiceProvider serviceProvider)
  {
    this._serivceProvider = serviceProvider;
  }

  public T Resolve<T>()
  {
     return _seriveProvider.GetService<T>();
  }
}


public class MyController : Controller 
{ 
  private IContainer contianer;
  public MyController(IContainer container)
  {
    this._container = container;
  }

  public IActionResult Get()
  {
    var service = _container.Resolve<IUserRepository>();
  }
}