ASP.NET Core的底层设计支持和使用依赖注入。ASP.NET Core 应用程序可以利用内置的框架服务将服务注入到启动类的方法中,并且应用程序服务也可以配置注入。由ASP.NET Core 提供的默认服务容器提供了最小功能集,并不是取代其他容器。
1.浅谈依赖注入
依赖注入(Dependency injection,DI)是一种实现对象和依赖者之间松耦合的技术,将类用来执行其操作的这些对象以注入的方式提供给该类,而不是直接实例化依赖项或者使用静态引用。一般情况,类会通过构造函数声明器2依赖关系,允许他们遵循显示依赖原则。这种方法称为“构造函数注入”。
当类的设计使用DI思想时,他们的耦合更加松散,因为他们没有对他们的合作者直接硬编码的依赖。这遵循“依赖倒置原则”,其中指出,高层模块不应该依赖于底层模块:两者都依赖于抽象。
类要求在他们构造时向其提供抽象(通常是接口),而不是引用特定的实现。提取接口的依赖关系和提供接口的实现作为参数也是“策略设计模式”的一个示例。
当一个类被用来创建类及其相关的依赖关系时,这个成为容器(containers),或者称为控制反转(Inversion of Control, IoC)容器,或者依赖注入容器。容器本质上是一个工厂,负责提供向它请求的类型的实例。如果一个给定类型声明它具有依赖关系,并且容器已经被配置为其提供依赖关系,那么它将把创建依赖关系作为创建请求实例的一部分。除了创建对象的依赖关系外,容器通常还会管理应用程序中对象的生命周期。
ASP.NET Core 包含一个默认支持构造函数注入的简单内置容器,ASP.NET 的容器指的是它管理的类型services,可以在Startup类的ConfigureServices方法中配置内置容器的服务。
2. 使用ASP.NET Core提供的服务
Startup类的ConfigureServices方法负责定义应用程序将使用的服务,包括平台自带的功能,比如,Entity Framework Core 和 ASP.NET Core MVC。除了IServiceCollection提供的几个服务之外,可以使用一些扩展方法(AddDbContext,AddMvc,AddTransient等)向容器添加和注册额外服务:
public void ConfigureServices(IServiceCollection services) { services.Configure<CookiePolicyOptions>(options => { // This lambda determines whether user consent for non-essential cookies is needed for a given request. options.CheckConsentNeeded = context => true; options.MinimumSameSitePolicy = SameSiteMode.None; }); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); services.AddDbContext<AccessManagementContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"), providerOptions => providerOptions.EnableRetryOnFailure())); services.AddTransient<ICompanyServices, CompanyServices>(); }
ASP.NET Core 提供的功能和中间件,遵循约定使用一个单一的AddService扩展方法来注册所有该功能所需的服务。
3.注册自己的服务
我们可以按照 services.AddTransient<ICompanyServices, CompanyServices>(); 这种写法注册自己的服务。第一个范型类型表示将要从容器中请求的类型(通常是一个接口)。第二个范型类型表示将由容器实例化并且用于完成请求的具体类型。
AddTransient 方法用于将抽象类型映射到为每一个需要它的对象分别实例化的具体服务。为注册的每一个服务选择合适的生命周期很重要,后面会介绍到。
下面是示例是注册自己的服务:
1.接口
public interface IAccountServices { Task<List<AccountViewModel>> GetList(); }
2.实现类
public class AccountServices:IAccountServices { AccessManagementContext _context; public AccountServices(AccessManagementContext context) { _context = context;//在构造函数中注入 } public async Task<List<Account>> GetList() { try { var query = _context.Account.ToListAsync(); return query ; } catch (Exception ex) { return null; } } }