WebAPI2使用Autofac實現IOC屬性注入完美解決方案

1、前言web

只要你是.NETer你必定IOC,IOC裏面你也會必定知道Autofac,上次說了在MVC5實現屬性注入,今天實如今WebApi2實現屬性注入,順便說一下autofac的程序集的注入方式,都會在後面的代碼裏面有提現api

在WebAPI2使用Autofac注入的時候大多數人會出現以下問題:安全

未能加載文件或程序集「System.Web.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35」或它的某一個依賴項。找到的程序集清單定義與程序集引用不匹配。 (異常來自 HRESULT:0x80131040)app

截圖以下:函數

這個是Autofac強依賴形成的,比較坑的。解決辦法以下。學習

Nuget添加Microsoft.AspNet.WebApiui

或經過NuGet 程序包管理器控制檯添加:spa

Install-Package Microsoft.AspNet.WebApi.net

Update-Package Microsoft.AspNet.WebApi -reinstall(存在)3d

緣由:咱們新建的是一個空的MVC項目,缺乏引用

 

先上個結構圖,結構圖只是爲了說明webAPI如何簡單使用Autofac實現屬性注入。

屬性注入存在安全隱患,官方建議使用構造函數注入。

下面說下具體實現:

2、代碼實現

一、新建一個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; }
    }

二、新建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);
    }

三、新建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()
        {
            return person;
        }
        public Person Get(int id)
        {
            return person.Find(p => p.Id == id);
        }
        public Person Add(Person item)
        {
            if (item == null)
            {
                throw new ArgumentNullException("item");
            }
            person.Add(item);
            return 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)
            {
                return false;
            }
            person.RemoveAt(index);
            person.Add(item);
            return true;
        }
        public bool Delete(int id)
        {
            person.RemoveAll(p => p.Id == id);
            return true;
        }
    }

四、新建WebAPI.IServices類庫,新建IPersonServices接口

    public interface IPersonServices
    {
        List<Person> GetAll();
    }

五、IPersonServices接口在WebAPI.Services類庫裏面PersonServices實現

    public class PersonServices : IPersonServices
    {
        //程序集屬性注入
        public IPersonRepository iPerson;

        public List<Person> GetAll()
        {
            return iPerson.GetAll();
        }
    }

六、新建一個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();
            //註冊全部的ApiControllers
            builder.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目錄下便可,不用引用dll
            var 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();
        }
    }

七、程序啓動注入

        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();
            return new string[] { "value1", "value2" };
        }

9.運行訪問api/values/,打個斷點看下搞定

3、總結

autofac確實用起來很方便,上面只是簡單的實現,若是想深刻學習能夠下載我上一個文章提供的兩個開源的項目能夠學習下,也能夠到autofac官網去了解下。

最近在看相關文章,不少都太專業化了沒怎麼看懂,這是本身如今對IoC的一些理解,記錄下來,要否則時間一久,也就忘了。

本身對IoC模式理解還很淺,但願獲得各位的指點。

代碼下載:

https://yunpan.cn/c6QCURhYmGcP9 (提取碼:e97a)

相關文章
相關標籤/搜索