介紹|術語
控制反轉:IOC和DI
- IOC
- 調用者不再創建(不自己new)被調用者的實例,而是交給容器去創建(AutoFac就充當這里的容器),這就是控制反轉
- 控制反轉中引入的第三方對象,通過Ioc容器將對象與對象的關系進行解耦,對象的創建與維護讓渡給第三方容器
- Ioc容器負責維護對象與對象之間的關系,並負責對象的創建和對象生命周期的維護
- DI
- 容器創建好的實例再注入調用者的過程,就是依賴注入(比如:屬性注入、構造函數注入等)
- 依賴注入就是將實例變量傳入到一個對象中去
- 控制反轉和依賴注入的關系
- 控制反轉是一種思想
- 依賴注入是一種設計模式
- 依賴倒置
依賴倒置(Dependence Inversion Principle,縮寫為DIP),是一種設計原則,是指:- 高層模塊不應該依賴底層模塊,都應該依賴於抽象
- 抽象不應該依賴於具體,具體依賴於抽象
原因:
+ 若高層依賴於底層,那么底層的變動也會導致高層的變動,這就會導致模塊的復用性降低而且大大提高了開發的成本。
+ 若是依賴於抽象的話,那么是比較穩定的,底層或者高層的變動都不會互相影響
控制反轉背后的核心思想是, 我們不再將類綁定在應用里,讓類自己去 "new up" 他們的依賴, 而是反過來在類的構造方法中將依賴傳遞進去
原理
尋找到相關實例,將其賦給接口對象。
組件|服務
public class SomeType : IService
{
}
在代碼中可以通過兩種方法訪問該類型(SomeType):
- 通過類型本身,
SomeType
- 通過接口,
IService
組件 指的是 SomeType
而它暴露的 服務 指的是 SomeType
和 IService
.
Autofac入門
MVC|Autofac手動注入
- 新建項目,ASP.NET MVC 5 Web應用程序
- 安裝Autofac和Autofac Integration mvc5
- 建立業務實體項目,解決方案右鍵,添加,新建項目,類庫,Models
- 建立業務邏輯項目,解決方案右鍵,添加,新建項目,類庫,Services
- 項目Services里面建立接口IGradeService
- 項目Services里面建立類GradeService,繼承接口IGradeService,實現方法
- 修改HomeController里面Index方法
public HomeController(IGradeService gradeService)
{
_gradeService = gradeService;
}
public ActionResult Index()
{
var model = _gradeService.GetAllGrade().ToList();
return View(model);
}
- 修改Global.asax,在Application_Start()方法里面添加如下代碼
public void Application_Start()
{
...
//依賴注入
var builder = new ContainerBuilder();
builder.RegisterType().As().InstancePerHttpRequest();
builder.RegisterControllers(Assembly.GetExecutingAssembly());
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
.AsImplementedInterfaces();
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}
MVC|Autofac自動注入
- 新建項目,ASP.NET MVC 5 Web應用程序
- 安裝Autofac和Autofac Integration mvc5
- 建立業務實體項目,解決方案右鍵,添加,新建項目,類庫,Models
- 建立業務邏輯項目,解決方案右鍵,添加,新建項目,類庫,Services
- 項目Services里面建立接口IDependency接口
namespace MvcApp5.Models
{
public interface IDependency
{
}
}
- 項目Services里面建立接口IGradeService抽象接口,其他任何的接口都需要繼承這個接口
- 項目Services里面建立類GradeService,繼承接口IGradeService,IDependency,實現IGradeService抽象接口方法
- 修改HomeController里面Index方法
public class HomeController : Controller
{
private readonly IModelCar _carmodel;
private readonly IModelUser _usermodel;
public HomeController(IModelCar carmodel,IModelUser usermodel)
{
_carmodel = carmodel;
_usermodel = usermodel;
}
public ActionResult Index()
{
ViewBag.Message = "修改此模板以快速啟動你的 ASP.NET MVC 應用程序。";
var carname=_carmodel.GetCarName();
var username = _usermodel.GetUserName();
return View();
}
}
- 修改Global.asax,在Application_Start()方法里面添加如下代碼
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
var builder=RegisterService();
DependencyResolver.SetResolver(new AutofacDependencyResolver(builder.Build()));
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AuthConfig.RegisterAuth();
}
private ContainerBuilder RegisterService()
{
var builder = new ContainerBuilder();
var baseType=typeof(IDependency);
var assemblys=AppDomain.CurrentDomain.GetAssemblies().ToList();
var AllServices = assemblys
.SelectMany(s => s.GetTypes())
.Where(p => baseType.IsAssignableFrom(p)&&p!=baseType);
builder.RegisterControllers(assemblys.ToArray());
builder.RegisterAssemblyTypes(assemblys.ToArray())
.Where(t =>baseType.IsAssignableFrom(t)&&t!=baseType)
.AsImplementedInterfaces().InstancePerLifetimeScope();
return builder;
}
}
API|Autofac自動注入
- 新建項目,ASP.NET Web應用程序,勾選MVC,API
- 安裝Autofac和Autofac Integration mvc5,Autofac.Integration.WebApi 2.X
- 建立業務實體項目,解決方案右鍵,添加,新建項目,類庫,Models
- 建立業務邏輯項目,解決方案右鍵,添加,新建項目,類庫,Services
- 項目Services里面建立接口IDependency接口
- 項目Services里面建立接口IGradeService抽象接口,其他任何的接口都需要繼承這個接口
- 項目Services里面建立類GradeService,繼承接口IGradeService,IDependency,實現IGradeService抽象接口方法
- 修改控制器代碼
public class ValuesController : ApiController
{
private readonly IUserService _UserService;
public ValuesController(IUserService UserService)
{
_UserService = UserService;
}
public IHttpActionResult Get(string name)
{
string str = _UserService.Set(name);
return Ok(str);
}
}
- 修改Global.asax,在Application_Start()方法里面添加如下代碼
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
#region 自動注入
//創建autofac管理注冊類的容器實例
var builder = new ContainerBuilder();
HttpConfiguration config = GlobalConfiguration.Configuration;
Assembly[] assemblies = Directory.GetFiles(AppDomain.CurrentDomain.RelativeSearchPath, "*.dll").Select(Assembly.LoadFrom).ToArray();
//注冊所有實現了 IDependency 接口的類型
Type baseType = typeof(IDependency);
builder.RegisterAssemblyTypes(assemblies)
.Where(type => baseType.IsAssignableFrom(type) && !type.IsAbstract)
.AsSelf().AsImplementedInterfaces()
.PropertiesAutowired().InstancePerLifetimeScope();
//注冊MVC類型
// builder.RegisterControllers(assemblies).PropertiesAutowired();
//注冊Api類型
builder.RegisterApiControllers(assemblies).PropertiesAutowired();
//builder.RegisterFilterProvider();
builder.RegisterWebApiFilterProvider(config);
var container = builder.Build();
//注冊api容器需要使用HttpConfiguration對象
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
//注冊解析
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
#endregion
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}