IOC容器之Autofac的使用:以MVC做演示
一. 创建一个空白MVC5的项目
二.添加Autofac (这里直接通过Nuget包添加) 添加Autofac.Mvc5
在添加时,部分人可能会报错! 提示无法安装Autofac 5.0
原因是MVC版本跟Autofac版本不兼容
我创建的MVc版本是5.0 此时安装Autofac时把Autofac的版本安装4.0.2 即解决了这个报错问题
三.编写代码
1.新建一个IService接口类
1 //定位Service程序集 2 public interface IService 3 { 4 }
创建需要注入的服务类
2.在新建一个用户服务类
1 using Entity; 2 public interface IUserService 3 { 4 string AddUserInfo(Sys_User user); 5 6 string GetUserPhone(string UserId); 7 } 8 9 public class UserService : IUserService 10 { 11 public string AddUserInfo(Sys_User user) 12 { 13 string newId = "1000000"; 14 return string.Format("{0},注册成功 ID为:{1}", user.Name, newId); 15 } 16 17 public string GetUserPhone(string UserId) 18 { 19 return "18900000000"; 20 } 21 }
3.在新建一个信息处理服务类
1 public interface IMessageService 2 { 3 void SendMessage(string Msg); 4 5 string GetMessage(string UserID); 6 } 7 8 public class MessageService : IMessageService 9 { 10 public string GetMessage(string UserID) 11 { 12 return "Hello World!"; 13 } 14 15 public void SendMessage(string Msg) 16 { 17 //发送成功 18 } 19 }
4.在创建一个ServiceLocator类,用来获取注入的服务
1 using Autofac;//引包 2 /// <summary> 3 /// Autofac的服务定位器 4 /// </summary> 5 public class ServiceLocator 6 { 7 private static IContainer _container; 8 9 /// <summary> 10 /// 设置Ico容器 11 /// </summary> 12 /// <param name="container"></param> 13 public static void SetContainer(IContainer container) 14 { 15 _container = container; 16 } 17 18 /// <summary> 19 /// 获取服务 20 /// </summary> 21 /// <typeparam name="IService"></typeparam> 22 /// <returns></returns> 23 public static IService GetService<IService>() 24 { 25 return _container.Resolve<IService>(); 26 } 27 28 /// <summary> 29 /// 获取容器对象 30 /// </summary> 31 /// <returns></returns> 32 public static IContainer GetContainer() 33 { 34 return _container; 35 } 36 }
5.在项目Global.asax中注册服务类
1 using Autofac; 2 using Autofac.Integration.Mvc; 3 using Service; 4 5 public class MvcApplication : System.Web.HttpApplication 6 { 7 protected void Application_Start() 8 { 9 AreaRegistration.RegisterAllAreas(); 10 RouteConfig.RegisterRoutes(RouteTable.Routes); 11 12 //获取Autofac容器构造器 13 var builder = new ContainerBuilder(); 14 //注册IService接口的程序集中包含Service的接口 15 builder.RegisterAssemblyTypes(typeof(Service.IService.IService).Assembly) 16 .Where(t => t.Name.EndsWith("Service")) 17 .AsImplementedInterfaces(); 18 //注册项目的Controllers 19 builder.RegisterControllers(System.Reflection.Assembly.GetExecutingAssembly()).PropertiesAutowired(); 20 21 //获取注入容器 22 var container = builder.Build(); 23 //设置服务容器 24 ServiceLocator.SetContainer(container); 25 //设置MVC的注入解析程序 26 DependencyResolver.SetResolver(new AutofacDependencyResolver(ServiceLocator.GetContainer())); 27 } 28 }
6.注入服务及调用
1 using Entity; 2 using Service; 3 using Service.IService; 4 public class HomeController : Controller 5 { 6 //两种方式获取注入的服务 7 8 private readonly IUserService userService; 9 //通过服务容器获取 10 private readonly IMessageService messageService = ServiceLocator.GetService<IMessageService>(); 11 12 //通过构造函数注入 13 public HomeController(IUserService _userService) 14 { 15 this.userService = _userService; 16 } 17 18 public ActionResult Index() 19 { 20 this.ViewBag.UserPhone = this.userService.GetUserPhone("张三"); 21 this.ViewBag.Message = this.messageService.GetMessage(""); 22 return View(); 23 } 24 }
7.测试结果
四.注册注意事项。
在Global.asax中注册服务类的时候 我们为了防止注册一些没有必要的实体类进去。添加了一句条件
加上这个注册条件后 就表示你的所有需要注入的服务类 的类名都必须以Service结尾。否则就会导致在使用时报没有注册的错误。
例如 下图:把UserService 类名改为 UserTest
解决此问题,也可以这样
注释那句注册时的筛选条件,但是值得注意的是,这样就会造成资源浪费,把在同一个程序集下面的非服务类也给注册进去了。
以上均为个人见解,不够深入!有什么错误的地方请见解。