DDD .NET Core 定义结构+依赖注入


工作有些年头了一直在搬砖,下定决心从零开始写一套领域模型的项目

把知道的东西变成会的,把会的东西融会贯通

最终能不能用无所谓,总要留点什么东西

Github 仓库地址

每一篇文章对应一个 tag

这版代码定义了

  领域模型中需要那些层

  层与层之间的基本引用

  使用.NET Core 内置的依赖注入框架,对各层之间进行解耦 (后面会替换成 Autofac)

由于项目之间只引用了接口没有引用实现,所以编译生成的DLL会缺少相关的实现

因此:

  一、各层编译后的DLL,都输出到同一个目录下

  二、Web项目,编译的时候把该项目中所有的DLL复制到 bin 文件中对应的路径下

项目结构

0-Infrastructure

  Core2022.Enum

  Core2022.Framework.Commons

  Core2022.Framework

1-Presentation

  Core2022.API Core2022.Web

2-Application

  Core2022.Application.Services

  Core2022.Application.Services.DTO

  Core2022.Application.Services.Interface

3-Domain

  Core2022.Domain

  Core2022.Domain.Model

  Core2022.Domain.Interface

4-Repository

  Core2022.Repository

  Core2022.Repository.Interface

引用关系

0-Infrastructure
  Core2022.Enum
  Core2022.Framework.Commons
  Core2022.Framework
1-Presentation
  Core2022.API
  Core2022.Web
    Core2022.Application.Services.DTO
    Core2022.Application.Services.Interface
2-Application
  Core2022.Application.Services
    Core2022.Application.Services.DTO
    Core2022.Application.Services.Interface
    Core2022.Domain.Model
    Core2022.Domain.Interface
    Core2022.Repository.Interface
  Core2022.Application.Services.DTO
  Core2022.Application.Services.Interface
    Core2022.Application.Services.DTO
3-Domain
  Core2022.Domain
    Core2022.Domain.Model
    Core2022.Domain.Interface
  Core2022.Domain.Model
  Core2022.Domain.Interface
4-Repository
  Core2022.Repository
    Core2022.Domain.Model
    Core2022.Domain.Interface
    Core2022.Repository.Interface
  Core2022.Repository.Interface
    Core2022.Domain.Model
    Core2022.Domain.Interface

依赖注入

在 Startup 中配置依赖注入,实现各层之间的解耦

InjectionServicesExtension.cs

using Core2022.Framework.Attributes;
using Core2022.Framework.Settings;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Reflection;

namespace Core2022.Framework.Commons.Injections
{
    /// 
    /// 
    /// 
    public static class InjectionServicesExtension
    {
        /// 
        /// 通过反射注册项目中的所有服务
        /// 
        /// 
        /// 
        /// 
        public static void InjectionServices(this IServiceCollection services, IConfiguration configuration)
        {
            foreach (var assemblyString in AppSettings.InjectionServices.AssemblyStrings)
            {
                var serviceTypes = Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory + assemblyString).GetTypes();
                if (serviceTypes != null && serviceTypes.Length > 0)
                {
                    foreach (var service in serviceTypes)
                    {
                        var attribute = service.GetCustomAttribute(typeof(InjectionAttribute), false);
                        if (attribute is InjectionAttribute)
                        {
                            InjectionAttribute injectionAttribute = attribute as InjectionAttribute;
                            var serviceInterfaceName = injectionAttribute.ServiceInterfaceName;
                            var serviceLifetime = injectionAttribute.ServiceLifetime;
                            AddInjectionWithLifetime(services, serviceLifetime, serviceInterfaceName, service);
                        }
                    }
                }
            }
        }

        /// 
        /// 向依赖框架中注册服务
        /// 
        /// 依赖框架
        /// 服务生命周期
        /// 服务
        /// 服务的实现
        /// 
        private static IServiceCollection AddInjectionWithLifetime(IServiceCollection services, ServiceLifetime serviceLifetime, Type service, Type implementation)
        {
            switch (serviceLifetime)
            {
                case ServiceLifetime.Scoped:
                    return services.AddScoped(service, implementation);
                case ServiceLifetime.Singleton:
                    return services.AddSingleton(service, implementation);
                case ServiceLifetime.Transient:
                    return services.AddTransient(service, implementation);
                default:
                    return services;
            }
        }
    }
}
InjectionAttribute.cs

using Microsoft.Extensions.DependencyInjection;
using System;


namespace Core2022.Framework.Attributes
{
    public class InjectionAttribute : Attribute
    {
        /// 
        /// 服务依赖的接口
        /// 
        public Type ServiceInterfaceName { get; set; }

        /// 
        /// 注册服务的生命周期
        /// 
        public ServiceLifetime ServiceLifetime { get; set; }

        /// 
        /// 依赖特性
        /// 
        /// 服务依赖接口
        /// 服务生命周期
        public InjectionAttribute(Type serviceInterfaceName, ServiceLifetime serviceLifetime = ServiceLifetime.Scoped)
        {
            ServiceInterfaceName = serviceInterfaceName;
            ServiceLifetime = serviceLifetime;
        }
    }
}
Startup.ConfigureServices

public void ConfigureServices(IServiceCollection services)
{
    services.InjectionInjectionOrmModel();
    //注册控制器和视图
    services.AddControllersWithViews();
    //注册服务
    services.InjectionServices(Configuration);
}
appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",

  /*注册服务 配置*/
  "InjectionServices": {
    "AssemblyStrings": [
      "Core2022.Domain.Model.dll",
      "Core2022.Application.Services.dll",
      "Core2022.Domain.dll",
      "Core2022.Repository.dll"
    ]
  }
}

这一版代码都属于基础知识,都是固定用法

唯一麻烦的就是编译项目的时候需要编译整个解决方案