namespace Library.Entity
{
//Book实体类:ID、姓名、作者
public class Book
{
public int Id { set; get; }
public string Name { set; get; }
public string Author { set; get; }
}
}
- 相当于对Model与Contorller的进一步解耦,里面封装了通用的业务逻辑、通用的数据接口等。
- 封装了与数据库的基本操作,供Controller层调用完成高层业务逻辑。
using Library.Entity;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Library.Services
{
//图书通用操作的的接口
public interface IBookRepository
{
Task<IEnumerable<Book>> GetBooksAsync(); //获取所有图书
Task<Book> GetBookAsync(int id); //根据ID获取相应图书
void AddBook(Book book); //增加图书
void UpdateBook(Book book); //更新图书
void DeleteBook(Book book); //删除图书
bool BookExistAsync(int id); //根据ID检测是否存在图书
}
}
using Library.Entity;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Library.Services
{
//图书通用操作的实现
public class BookRepository : IBookRepository
{
//DbContext 数据库实体,由EF框架去进行SQL操作
private readonly LibraryDbContext _context;
public BookRepository(LibraryDbContext context)
{
_context = context;
}
//增加图书
public void AddBook(Book book)
{
_context.Books.Add(book);
_context.SaveChanges();
}
///
/// 根据ID检测是否存在图书
///
///
/// true or false
public bool BookExistAsync(int id)
{
return _context.Books.Any(x => x.Id == id);
}
//删除图书
public void DeleteBook(Book book)
{
_context.Books.Remove(book);
_context.SaveChanges();
}
//获取所有图书
public async Task<IEnumerable<Book>> GetBooksAsync()
{
return await _context.Books.ToListAsync();
}
//根据ID获取图书
public async Task<Book> GetBookAsync(int id)
{
return await _context.Books
.Where(x => x.Id == id)
.FirstOrDefaultAsync();
}
//更新图书
public void UpdateBook(Book book)
{
_context.Update(book);
_context.SaveChanges();
}
}
}
using Library.Entity;
using Library.Services;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Threading.Tasks;
namespace Library.Controller
{
[Route("api/[controller]")]
[ApiController]
public class BooksController : ControllerBase
{
//IBookRepository 对象实体,内含通用的业务逻辑
private readonly IBookRepository _bookRepository;
public BooksController(IBookRepository bookRepository)
{
_bookRepository = bookRepository;
}
[HttpGet] //api/Books
public async Task<IActionResult> GetBooks()
{
var books = await _bookRepository.GetBooksAsync();
return Ok(books);
}
[HttpGet("{id}")]//api/Books/id
public async Task<IActionResult> GetBook(int id)
{
var book = await _bookRepository.GetBookAsync(id);
if (book == null)
{
return NotFound();
}
else return Ok(book);
}
[HttpDelete]
public void DeleteBook(Book book)
{
if (_bookRepository.BookExistAsync(book.Id))
{
_bookRepository.DeleteBook(book);
}
else throw new InvalidOperationException();
}
[HttpPost]
public void AddBook(Book book)
{
if (!_bookRepository.BookExistAsync(book.Id))
{
_bookRepository.AddBook(book);
}
else throw new InvalidOperationException();
}
[HttpPut]
public void UpdateBook(Book book)
{
if (_bookRepository.BookExistAsync(book.Id))
{
_bookRepository.UpdateBook(book);
}
else throw new InvalidOperationException();
}
}
}
DbContext:数据库上下文类:是EF中重要的一环,它是数据库与你应用程序域或实体类的桥梁。
DbContext 是负责数据与对象互操作的主要的类型。它主要负责以下一些动作:
- EntitySet : DbContext 包含所有从数据库表中被映射出来的实体对象的集合(如DbSet<>)。
- Querying : DbContext 将LINQ To Entities 转化为SQL 查询语句并发送至数据库。
- Change Tracking : 它保持变更追踪,一旦实体对象发生改变它就会从数据库中进行查询。
- Persisting Data : 它也可以基于实体状态对数据库进行插入,更新和删除操作。
- Caching : DbContext 默认作一级缓存,它存储在上下文类的生命周期中检索过的实体对象。
- Manage Relationship : 在DB-First 或 Model-First 中 DbContext 使用CSDL, MSL 和 SSDL 管理关系,在Code-First中使用流式API管理关系。
- Object Materialization : DbContext 将原始的表数据转化至实体对象中。
"ConnectionStrings": {
"MysqlConnection": "Data Source=localhost;port=3306;Initial catalog=library;User ID=root;Password=root; treatTinyAsBoolean=false;"
}
services.AddDbContext<LibraryDbContext>(opthion =>
{
opthion.UseMySql(Configuration.GetConnectionString("MysqlConnection"));
});
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>(); //使用UseStarup<>
});
}
宿主机提供了一些能写入Startup类构造函数的服务。应用程序通过 ConfigureServices类来添加其他服务,同时主机和服务都可以在Configure 类和整个应用中使用。
Startup类中包括ConfigureService方法和Configure方法。
– ConfigureService:This method gets called by the runtime. Use this method to add services to the container.
- The host may configure some services before Startup methods are called.
- For features that require substantial setup, there are Add{Service} extension methods on IServiceCollection. For example, AddDbContext, AddDefaultIdentity, AddEntityFrameworkStores, and AddRazorPages
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.AddScoped<IBookRepository, BookRepository>();
services.AddDbContext<LibraryDbContext>(opthion =>
{
opthion.UseMySql(Configuration.GetConnectionString("MysqlConnection"));
});
services.AddControllers();
}
– Configure:This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
- The Configure method is used to specify how the app responds to HTTP requests.
- The request pipeline is configured by adding middleware components to an IApplicationBuilder instance.
//注入服务管道
// 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();
});
}
- 通过依赖注入(DI)来实现控制反转(IOC)。
- ASP.NET Core 提供了一个内置的服务容器 IServiceProvider。 服务已在应用的Startup.ConfigureServices 方法中注册。
- 将服务注入到使用它的类的构造函数中。 框架负责创建依赖关系的实例,并在不再需要时对其进行处理。
- AddSingleton
:项目启动-项目关闭 相当于静态类 只会有一个 - AddScoped
:请求开始-请求结束 在这次请求中获取的对象都是同一个 - AddTransient
:请求获取-(GC回收-主动释放) 每一次获取的对象都不是同一个
- 选择是否将请求传递到管道中的下一个组件。
- 可在管道中的下一个组件前后执行工作。
依赖关系注入 (DI)
Logging
Configuration
IHostedService 实现
调用 CreateHostBuilder 方法以创建和配置生成器对象。
对生成器对象调用 Build 和 Run 方法。
其主要涉及到两个关键对象IHostBuilder和IHost,它们的内部实现是ASP.NET Core应用的核心所在。
- CreateHostBuilder(args) :方法创建了一个IHostBuilder 抽象对象,创建过程包含CreateDefaultBuilder(args)
- CreateDefaultBuilder(args):开启创建一个默认的通用宿主机Host建造者,再通过ConfigureWebHostDefaults()方法配置开启默认的Kestrel 为默认的Web服务器并对其进行默认配置,并集成对iis的集成
- Build() :负责创建IHost,看过源代码的同学可以发现Build的过程 会配置各种东西,本身通过管道模式进行了一系列的默认或者自定义的配置以及服务注册的构建
- Run() :启动IHost。
- UseContentRoot:指定Web host使用的content root(内容根目录),比如Views。默认为当前应用程序根目录。
- ConfigureHostConfiguration :启动时宿主机需要的环境变量等相关,支持命令行
- ConfigureAppConfiguration:设置当前应用程序配置。主要是读取 appsettinggs.json 配置文件、开发环境中配置的UserSecrets、添加环境变量和命令行参数 。
- ConfigureLogging:读取配置文件中的Logging节点,配置日志系统。
- UseDefaultServiceProvider:设置默认的依赖注入容器。
- UseStaticWebAssets:静态文件环境的配置启用
- UseKestrel:开启Kestrel为默认的web 服务器.
- ConfigureServices:服务中间件的注册,包含路由的中间件的注册
- UseIIS:对iis 集成的支持
- UseStartup:程序Startup 启动,该启动类中可以注册中间件、扩展第三方中间件,以及相关应用程序配置的处理等等操作。
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)//开启一个默认的通用主机Host建造者
.ConfigureAppConfiguration(config => {
//注册应用程序内所使用的配置文件,比如数据库链接等等
Console.WriteLine("ConfigureAppConfiguration");
})
.ConfigureServices(service =>
{
//注册服务中间件等操作
Console.WriteLine("ConfigureServices");
})
.ConfigureHostConfiguration(builder => {
//启动时需要的组件配置等,比如监听的端口 url地址等
Console.WriteLine("ConfigureHostCOnfiguration");
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}