ASP.NET 多层应用程序迁移到 ASP.NET 核心

ASP.NET MultiLayer App Migration To ASP.NET Core

我将我的 ASP.NET 多层项目迁移到 ASP.NET Core。我在我的旧项目中使用 Ninject 作为 DI,我可以在我的 BLL 中如下调用它。

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

现在我当然用ASPNet Core的DI系统。但是我怎样才能在业务层为 ASP.NET 核心调用服务定位器呢?我需要你的样品和建议。

在Startup.cs

services.AddScoped<IProdCalcService,ProdCalcManager>();

在 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()
    ..
}

最好不要使用服务定位器,但在这种情况下,您可以将 ServiceProvider 注入到您的 Controller 中,或者更好的解决方案是将 ServiceProvider 包装并抽象到一个可以简单注入的容器中。 在这种情况下,我更喜欢使用 3rd 方 DI 容器,特别是 CastleCore 是个不错的选择。

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>();
  }
}

正确答案是:不要使用 ServiceLocator。像你一样使用 services.AddScoped<T> 注册你的服务,然后将其添加到你想在其中使用它的 class 的构造函数中。

像这样:

services.AddScoped<IProdCalcService,ProdCalcManager>();

那么你的 class 看起来像这样:

public class MyClass()
{

    private IProdCalcService calcService;

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

    public void IamMethodInBll()
    {

        //...

        prodSurr.CalculatedPrice = calcService.GetMyMethod();

        //...
    }
}