-
asp.net mvc core 内置了 IOC 容器,不再需要 autofac 等,当然 autofac 也是支持.net core
的(http://www.open-open.com/lib/view/open1454127071933.html)。内置 IOC 是通过构
造函数注入,而不是属性注入. -
内置的 IOC 有三种生命周期:
Transient: Transient 服务在每次被请求时都会被创建。这种生命周期比较适用于轻量级的
无状态服务。
Scoped: Scoped 生命周期的服务是每次 web 请求被创建。
Singleton: Singleton 生命能够周期服务在第一被请求时创建,在后续的每个请求都会使用
同一个实例。如果你的应用需要单例服务,推荐的做法是交给服务容器来负责单例的创建和
生命周期管理,而不是自己来走这些事情。 - 使用方法:服务注册是在Startup类的ConfigureServices方法你进行注册的。下面举例说明:
public interface IUserService { string GetStr(); } public class UserService : IUserService { public string GetStr() { return "hello"; } }
加入我们要以Singleton的方式让IOC容器替我们创建UserService对象,则我们只需要在Startup类的ConfigureServices方法里面调用services.AddSingleton方法
public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddSingleton(typeof(IUserService), typeof(UserService));//最好 services.AddSingleton(typeof(IMyService),typeof(MyService));
因为这样的话可以在 MyService 中通过构造函数注入其他服务 }
这样以后,Controller里我们使用UserService这个类的时候,就不需要自己New创建,而是需要的时候有IOC容器帮我们创建。
public class HomeController : Controller { private IUserService userService; public HomeController(IUserService _userService) { userService = _userService; } public IActionResult Index() { string connStr = userService.GetStr(); //return View(); return Content(connStr); } }
实际项目中,我们会写许多的接口,这个时候可以通过放射的方式注入服务接口
var serviceAsm = Assembly.Load(new AssemblyName("CoreProj.Service")); foreach(Type serviceType in serviceAsm.GetTypes() .Where(t=>typeof(IServiceTag).IsAssignableFrom(t)&&!t.GetTypeInfo().IsAbstract)) { var interfaceTypes = serviceType.GetInterfaces(); foreach(var interfaceType in interfaceTypes) { services.AddSingleton(interfaceType, serviceType); } }
- 其他类中的注入(例如过滤器Filter中)
确保ExceptionFilter 不是 new 出来的,而是 IOC 创建出来即可。
public void ConfigureServices(IServiceCollection services) { var serviceAsm = Assembly.Load(new AssemblyName("CoreProj.ServiceImpl")); foreach (Type serviceType in serviceAsm.GetTypes() .Where(t => typeof(IServiceSupport).IsAssignableFrom(t) && !t.GetTypeInfo().IsAbstract)) { var interfaceTypes = serviceType.GetInterfaces(); foreach (var interfaceType in interfaceTypes) { services.AddSingleton(interfaceType, serviceType); } } services.AddSingleton(typeof(MyExceptionFilter));//放在AddMVC前面,首先在IOC中注册MyExceptionFilter //mvc core中注册filter要在AddMvc的回调方法中注册。 //services.AddMvc(mvcOptions => //{ // var serviceProvider = services.BuildServiceProvider(); // var exceptionFilter = serviceProvider.GetService<MyExceptionFilter>();//手动获得 // mvcOptions.Filters.Add(exceptionFilter); //});//两种写法都可以 services.AddMvc(mvcOptions => { mvcOptions.Filters.Add(typeof(MyExceptionFilter)); });
- 手动获取对象
1.通过serviceProvider.GetService<IUserService>()获取(可以将serviceProvider写成static)
2.HttpContext 可用的时候,也可以通过这种方法来解析服务: IPostService ps =
(IPostService)this.HttpContext.RequestServices.GetService(typeof(IPostService));
- MVC Core内置的注入其他服务(https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection)
例如: ILogger,IHostingEnvironment服务等
IHostingEnvironment主要成员:
WebRootPath 属性(wwwroot 文件 夹 的 物 理 路 径 )(MVC Core中没有Server.MapPath方法)
ContentRootPath 属 性 ( 网 站 根 目 录 的 物 理 路 径 )
Microsoft.AspNetCore.Hosting 下的 HostingEnvironmentExtensions 下还提供了一些扩展方法:
IsDevelopment()是否是开发环境
IsProduction()是否是生产环境
public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .UseEnvironment("Production")//Development//此处设置当前运行环境(可以写到配置文件中) .Build(); }