我将如何解决第 3 层或第 4 层上的接口依赖关系

How will i resolve Dependency of interfaces which is on 3rd or 4rth layer

我正在 Dotnet Core 3.1 中创建架构。

我创建了图层

API

-> 控制器

-> 服务接口。 (这个会被Controller Layer用到)

-> 服务实施

-> 数据接口。 (这将被服务实现层作为依赖使用)

->数据实现

我不想将我的数据实现暴露给控制器层,但它必须在服务实现层的构造函数中使用。

问题是:

如何解析数据实现类?

以及如何在 IServiceCollection 中注册这些 类?

您可以通过以下方式做到这一点:

  1. 为每一层定义单独的项目。
  2. 根据需要设置层之间的依赖关系。
  3. 模型映射应该在Service Layer而不是在Controller层(通常应该在Controller层,但在您的场景中不适用)。
  4. 在您的 Service Layer
  5. 中安装 Microsoft.Extensions.DependencyInjection NuGet
  6. Service Layer 中的 DependencyInjection 定义扩展方法。
  7. 调用Startup.cs中的扩展方法

我准备了一个例子来解释答案。

示例:

具有依赖关系的解决方案框架:

示例产品端点接口和 classes 解决方案分布

端点服务的依赖注入

控制器Class代码:

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using TestProj.AppServices.Interfaces;

namespace TestProj.Api.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class ProductsController : ControllerBase
    {
        private readonly ILogger<ProductsController> _logger;
        private readonly IProductService _service;

        public ProductsController(ILogger<ProductsController> logger,
                                  IProductService service)
        {
            _logger = logger;
            _service = service;
        }

        [HttpGet("{id=1}")] //Set default value for example only, it should be [HttpGet("{id}")]
        public IActionResult Get(int id)
        {
            return Ok(_service.GetById(id));
        }
    }
}

产品服务

    using TestProj.AppServices.Interfaces;
    using TestProj.AppServices.Models;
    using TestProj.Data.Interfaces;
    
    namespace TestProj.AppServices.AppServices
    {
        public class ProductService : IProductService
        {
            private readonly IProductRepository _repository;
    
            public ProductService(IProductRepository repository)
            {
                _repository = repository;
            }
            public Product GetById(int id)
            {
                //Subject code here
    
                //Dummy code:
                var productFromDataLayer = _repository.GetById(id);
    
                //Mapping (You can use AutoMapper NuGet)
                var product = new Product
                {
                    Id = productFromDataLayer.Id,
                    Name = productFromDataLayer.Name
                };
    
                return product;
            }
        }
    }

IProductService

using TestProj.AppServices.Models;

namespace TestProj.AppServices.Interfaces
{
    public interface IProductService
    {
        Product GetById(int id);
    }
}

产品服务层模型

namespace TestProj.AppServices.Models
{
    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
}

产品资料库

using TestProj.Data.Interfaces;
using TestProj.Data.Model;

namespace TestProj.Data.Data
{
    public class ProductRepository : IProductRepository
    {
        public Product GetById(int id)
        {
            //Subject code here

            //Dummy code:
            var product = new Product
            {
                Id = 1,
                Name = "Product 1"
            };

            return product;
        }
    }
}

IProductRepository

using TestProj.Data.Model;

namespace TestProj.Data.Interfaces
{
    public interface IProductRepository
    {
        Product GetById(int id);
    }
}

数据层产品模型(实体)

namespace TestProj.Data.Model
{
    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
}

依赖注入扩展Class

using Microsoft.Extensions.DependencyInjection;
using TestProj.AppServices.AppServices;
using TestProj.AppServices.Interfaces;
using TestProj.Data.Data;
using TestProj.Data.Interfaces;

namespace TestProj.AppServices.Others
{
    public static class DependencyInjection
    {
        public static void AddProjectServicesAndRepositoresDependencyInjection(this IServiceCollection services)
        {

            //Services
            services.AddTransient<IProductService, ProductService>();

            //Data
            services.AddTransient<IProductRepository, ProductRepository>();
        }
    }
}

启动class

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using TestProj.AppServices.Others;

namespace TestProj.Api
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddProjectServicesAndRepositoresDependencyInjection();

            services.AddControllers();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}

示例源码我已经上传到GitHubhttps://github.com/ualehosaini/LayeredArchitecturePreparedToAnswerForAWhosebugQuestion。您可以将它用于您的项目,您可以 define/add 您需要的任何组件。