.net core中服务注册的几种方式
IServiceCollection的Add方法
首先要知道在Startup配置类中有两个方法比较重要的方法,Configure和ConfigureServices方法,前者经常用来添加中间件,后者则是我们注册服务的位置。
IServicesCollection的Add方法接受一个ServiceDescriptor对象为参数,以下是官方文档给出的构造函数:
不难看出大致有这样几个参数:IService接口类型、Instance或Object表示具体的实现类,最后一个参数表示服务的生命周期,给一段示例代码:
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Add(new ServiceDescriptor(typeof(IMyService), typeof(MyService), ServiceLifetime.Scoped));
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
不难理解,IServiceCollection实际上是一个ServiceDescriptor类型的集合,用接口类型、接口实现类和生命周期来描述容器中的服务。
服务的生命周期
Singleton:容器会创建并共享服务的单例,且一直会存在于应用程序的整个生命周期内。Transient:每次服务被请求时,总会创建新实例。Scoped:在每一次请求时会创建服务的新实例,并在这个请求内一直共享这个实例。
生命周期扩展方法
//Singleton
services.AddSingleton(typeof(IMyService), typeof(MyService));
services.AddSingleton<IMyService,MyService>();
services.AddScoped<IMyService>(temp => new MyService());
//Scoped
services.AddScoped(typeof(IMyService), typeof(MyService));
services.AddScoped<IMyService, MyService>();
services.AddScoped<IMyService>(temp => new MyService());
给一张官网文档的截图,推荐使用上述示例代码中最后一种方式(因为支持的特性最多)
依赖项的几种注入方式
构造器注入
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
private readonly IMyService myService;
public ValuesController(IMyService myService)
{
this.myService = myService;
}
// GET api/values
[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
return new string[] { "value1", "value2" };
}
}
FromServices方法注入
public IActionResult About([FromServices] IDateTime dateTime)
{
return Content( $"Current server time: {dateTime.Now}");
}
从json配置文件读取配置
------------华丽的分割线--------
不巧没用过,不会
官方文档:服务的依赖注入注册
将依赖项注入到Controller
MVC
要在ASP.NET Core中使用MVC,首先需要在Startup类中添加MVC中间件:
Configure方法:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseMvc();
}
ConfigureServices方法:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
路由
在.net core MVC中路由负责解析URL,并将拆解出来的信息处理后把请求交给特定Controller中的特定Action,Action是在controller中的方法,将请求处理完毕后返回特定的视图View(可能是Razor生成的cshtml也可能是html)或者特定格式的数据(JSON)。
比较麻烦的方式创建路由
先从不好学的学起方便后续理解。
1.添加路由相关的服务
public void ConfigureServices(IServicesCollection services){
services.AddRouting();
}
2.配置路由中间件
public void Configure(IApplicationBuilder app,IHostingEnironment evn)
{
//创建路由处理器RouteHandler,输出路由信息
var routeHandler = new RouteHandler(context =>
{
var values = context.GetRouteData().Values;
return context.Response.WriteAsync($"路由信息{string.Join(",", values)}");
});
//创建RouteBuilder
var routeBuilder = new RouteBuilder(app, routeHandler);
//MapRoute方法
routeBuilder.MapRoute("api/hello", context =>
{
return context.Response.WriteAsync(JsonConvert.SerializeObject(new
{
name="hello路由",
message="返回一个JSON对象"
}));
});
routeBuilder.MapRoute("Route1", "api/{operation}/{id:int}");
routeBuilder.MapGet("hello/{prama1}", context =>
{
var prama1 = context.GetRouteValue("prama1");
return context.Response.WriteAsync($"hello后参数:{prama1}");
});
routeBuilder.MapRoute("default", "api/{Controller}/{Action}");
IRouter routes = routeBuilder.Build();
//调用IApplicationBuilder的UseRouter扩展方法来添加路由中间件
app.UseRouter(routes);
}
RouteHandler只有一个构造器,没有重载,接受RequestDelegate类型的参数。
RequestDelegate接收一个HttpContext类型的参数返回值为Task类型。
以下是几种匹配路由的结果:
-
匹配到第一个路由:
-
匹配到第二个路由
-
匹配到第三个路由
-
默认路由
除了IApplicationBuilder的UseRouter方法外,在添加MVC中间件时使用的UseMvc方法也可以配置路由信息,以下是UseMvc的方法签名:
可以看到其中一个扩展方法接受Action(这个Action是一个委托,接受一个IRouteBuilder类型的参数),这就有操作空间了,所以路由还可以这么写:
用UseMvc扩展方法配置路由:
//UseMvc方法:
app.UseMvc(routes =>
{
routes.MapRoute(
name:"myRoute",
template:"{controller}/{action}",
defaults: new { Controller = "My", Action = "Hello"}
);
});
//Controller
public class MyController: Controller
{
public IActionResult Hello()
{
return Ok("这里是HelloAction");
}
}
请求以及响应结果:
正经人写的路由
因为上面的写法有些是2.1版本的(其实.net framework里面路由就这么写),下面继续学习3.1