WebAPI2使用Autofac实现IOC属性注入完美解决方案
一、前言
只要你是.NETer你一定IOC,IOC里面你也会一定知道Autofac,上次说了在MVC5实现属性注入,今天实现在WebApi2实现属性注入,顺便说一下autofac的程序集的注入方式,都会在后面的代码里面有提现
在WebAPI2使用Autofac注入的时候大多数人会出现如下问题:
未能加载文件或程序集“System.Web.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35”或它的某一个依赖项。找到的程序集清单定义与程序集引用不匹配。 (异常来自 HRESULT:0x80131040)
截图如下:
这个是Autofac强依赖造成的,比较坑的。解决办法如下。
Nuget添加Microsoft.AspNet.WebApi
或通过NuGet 程序包管理器控制台添加:
Install-Package Microsoft.AspNet.WebApi
Update-Package Microsoft.AspNet.WebApi -reinstall(存在)
原因:我们新建的是一个空的MVC项目,缺少引用
先上个结构图,结构图只是为了说明webAPI如何简单使用Autofac实现属性注入。
属性注入存在安全隐患,官方建议使用构造函数注入。
下面说下具体实现:
二、代码实现
1、新建一个WebAPI.Entity类库,新建一个Person.cs类
public class Person{public int Id { get; set; }public string Name { get; set; }public int Age { get; set; }public string Address { get; set; }}
2、新建WebAPI.IRepository类库,新建一个IPersonRepository类
public interface IPersonRepository{List<Person> GetAll();Person Get(int id);Person Add(Person item);bool Update(Person item);bool Delete(int id);}
3、新建WebAPI.Repository类库,新建一个PersonRepository类实现IPersonRepository接口
public class PersonRepository : IPersonRepository{List<Person> person = new List<Person>();public PersonRepository(){Add(new Person { Id = 1, Name = "joye.net1", Age = 18, Address = "中国上海" });Add(new Person { Id = 2, Name = "joye.net2", Age = 18, Address = "中国上海" });Add(new Person { Id = 3, Name = "joye.net3", Age = 18, Address = "中国上海" });}public List<Person> GetAll(){retu person;}public Person Get(int id){retu person.Find(p => p.Id == id);}public Person Add(Person item){if (item == null){throw new ArgumentNullException("item");}person.Add(item);retu item;}public bool Update(Person item){if (item == null){throw new ArgumentNullException("item");}int index = person.FindIndex(p => p.Id == item.Id);if (index == -1){retu false;}person.RemoveAt(index);person.Add(item);retu true;}public bool Delete(int id){person.RemoveAll(p => p.Id == id);retu true;}}
4、新建WebAPI.IServices类库,新建IPersonServices接口
public interface IPersonServices{List<Person> GetAll();}
5、IPersonServices接口在WebAPI.Services类库里面PersonServices实现
public class PersonServices : IPersonServices{//程序集属性注入public IPersonRepository iPerson;public List<Person> GetAll(){retu iPerson.GetAll();}}
6、新建一个WebAPI项目WebAPI,新建AutoFacBootStrapper类,nuget安装autofac
public class AutoFacBootStrapper{public static void CoreAutoFacInit(){var builder = new ContainerBuilder();HttpConfiguration config = GlobalConfiguration.Configuration;SetupResolveRules(builder);////注册所有的Controllers//builder.RegisterControllers(Assembly.GetExecutingAssembly()).PropertiesAutowired();//注册所有的ApiControllersbuilder.RegisterApiControllers(Assembly.GetExecutingAssembly()).PropertiesAutowired();var container = builder.Build();//注册api容器需要使用HttpConfiguration对象config.DependencyResolver = new AutofacWebApiDependencyResolver(container);DependencyResolver.SetResolver(new AutofacDependencyResolver(container));}private static void SetupResolveRules(ContainerBuilder builder){//WebAPI只用引用services和repository的接口,不用引用实现的dll。//如需加载实现的程序集,将dll拷贝到bin目录下即可,不用引用dllvar iServices = Assembly.Load("WebAPI.IServices");var services = Assembly.Load("WebAPI.Services");var iRepository = Assembly.Load("WebAPI.IRepository");var repository = Assembly.Load("WebAPI.Repository");//根据名称约定(服务层的接口和实现均以Services结尾),实现服务接口和服务实现的依赖builder.RegisterAssemblyTypes(iServices, services) .Where(t => t.Name.EndsWith("Services")) .AsImplementedInterfaces();//根据名称约定(数据访问层的接口和实现均以Repository结尾),实现数据访问接口和数据访问实现的依赖builder.RegisterAssemblyTypes(iRepository, repository) .Where(t => t.Name.EndsWith("Repository")) .AsImplementedInterfaces();}}
7、程序启动注入
protected void Application_Start(){GlobalConfiguration.Configure(WebApiConfig.Register);AreaRegistration.RegisterAllAreas();RouteConfig.RegisterRoutes(RouteTable.Routes);FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);BundleConfig.RegisterBundles(BundleTable.Bundles);//程序启动注入AutoFacBootStrapper.CoreAutoFacInit();}
8.接口调用数据
public IPersonServices IServices { get; set; }// GET api/<controller>public IEnumerable<string> Get(){var list = IServices.GetAll();retu new string[] { "value1", "value2" };}
9.运行访问api/values/,打个断点看下搞定
三、总结
autofac确实用起来很方便,上面只是简单的实现,如果想深入学习可以下载我上一个文章提供的两个开源的项目可以学习下,也可以到autofac官网去了解下。
最近在看相关文章,很多都太专业化了没怎么看懂,这是自己现在对IoC的一些理解,记录下来,要不然时间一久,也就忘了。
自己对IoC模式理解还很浅,希望得到各位的指点。
代码下载:
https://yunpan.cn/c6QCURhYmGcP9 (提取码:e97a)
作者:Joye.Net
来源链接:https://www.cnblogs.com/yinrq/p/5383396.html
版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。
2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。