1.依賴注入的目的是爲了解耦。html
2.不依賴於具體類,而依賴抽象類或者接口,這叫依賴倒置。git
3.控制反轉即IoC (Inversion of Control),它把傳統上由程序代碼直接操控的對象的調用權交給容器,經過容器來實現對象組件的裝配和管理。所謂的「控制反轉」概念就是對組件對象控制權的轉移,從程序代碼自己轉移到了外部容器。api
4. 微軟的DependencyResolver如何建立controller mvc
一、InstancePerDependencyapp
對每個依賴或每一次調用建立一個新的惟一的實例。這也是默認的建立實例的方式。框架
官方文檔解釋:Configure the component so that every dependent component or call to Resolve() gets a new, unique instance (default.) asp.net
二、InstancePerLifetimeScopeide
在一個生命週期域中,每個依賴或調用建立一個單一的共享的實例,且每個不一樣的生命週期域,實例是惟一的,不共享的。函數
官方文檔解釋:Configure the component so that every dependent component or call to Resolve() within a single ILifetimeScope gets the same, shared instance. Dependent components in different lifetime scopes will get different instances. ui
三、InstancePerMatchingLifetimeScope
在一個作標識的生命週期域中,每個依賴或調用建立一個單一的共享的實例。打了標識了的生命週期域中的子標識域中能夠共享父級域中的實例。若在整個繼承層次中沒有找到打標識的生命週期域,則會拋出異常:DependencyResolutionException。
官方文檔解釋:Configure the component so that every dependent component or call to Resolve() within a ILifetimeScope tagged with any of the provided tags value gets the same, shared instance. Dependent components in lifetime scopes that are children of the tagged scope will share the parent's instance. If no appropriately tagged scope can be found in the hierarchy an DependencyResolutionException is thrown.
四、InstancePerOwned
在一個生命週期域中所擁有的實例建立的生命週期中,每個依賴組件或調用Resolve()方法建立一個單一的共享的實例,而且子生命週期域共享父生命週期域中的實例。若在繼承層級中沒有發現合適的擁有子實例的生命週期域,則拋出異常:DependencyResolutionException。
官方文檔解釋:Configure the component so that every dependent component or call to Resolve() within a ILifetimeScope created by an owned instance gets the same, shared instance. Dependent components in lifetime scopes that are children of the owned instance scope will share the parent's instance. If no appropriate owned instance scope can be found in the hierarchy an DependencyResolutionException is thrown.
五、SingleInstance
每一次依賴組件或調用Resolve()方法都會獲得一個相同的共享的實例。其實就是單例模式。
官方文檔解釋:Configure the component so that every dependent component or call to Resolve() gets the same, shared instance.
六、InstancePerHttpRequest (新版autofac建議使用InstancePerRequest)
在一次Http請求上下文中,共享一個組件實例。僅適用於asp.net mvc開發。
官方文檔解釋:Share one instance of the component within the context of a single HTTP request.
<?xml version="1.0"?> <configuration> <configSections> <section name="autofac" type="Autofac.Configuration.SectionHandler, Autofac.Configuration"/> </configSections> <autofac defaultAssembly="ConsoleApplication1"> <components> <component type="ConsoleApplication1.SqlDAL, ConsoleApplication1" service="ConsoleApplication1.IDAL" /> </components> </autofac> </configuration>
static void Main(string[] args) { ContainerBuilder builder = new ContainerBuilder(); builder.RegisterType<DBManager>(); builder.RegisterModule(new ConfigurationSettingsReader("autofac")); using (IContainer container = builder.Build()) { DBManager manager = container.Resolve<DBManager>(); manager.Add("INSERT INTO Persons VALUES ('Man', '25', 'WangW', 'Shanghai')"); }
MVC5示例中實現的功能有:程序集註冊、按服務註冊、屬性注入、泛型注入
global.cs
public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); InitDependency(); StackExchange.Profiling.EntityFramework6.MiniProfilerEF6.Initialize(); } private void InitDependency() { ContainerBuilder builder = new ContainerBuilder(); Type baseType = typeof(IDependency); // 自動註冊當前程序集 //builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).AsImplementedInterfaces(); // 註冊當前程序集 Assembly assemblies = Assembly.GetExecutingAssembly(); builder.RegisterAssemblyTypes(assemblies) .Where(type => baseType.IsAssignableFrom(type) && !type.IsAbstract) .AsImplementedInterfaces().InstancePerLifetimeScope();//保證對象生命週期基於請求 //註冊引用的程序集 //var assemblyList = BuildManager.GetReferencedAssemblies().Cast<Assembly>().Where(assembly => assembly.GetTypes().Any(type => type.GetInterfaces().Contains(baseType))); //var enumerable = assemblyList as Assembly[] ?? assemblyList.ToArray(); //if (enumerable.Any()) //{ // builder.RegisterAssemblyTypes(enumerable) // .Where(type => type.GetInterfaces().Contains(baseType)) // .AsImplementedInterfaces().InstancePerLifetimeScope(); //} //註冊指定的程序集 //自動註冊了IStudentService、IUserService builder.RegisterAssemblyTypes(Assembly.Load("AppService"), Assembly.Load("AppService")) .Where(t => t.Name.EndsWith("Service")) .AsImplementedInterfaces(); //1、Type註冊服務 builder.RegisterType<CourseService>().As<ICourseService>(); builder.RegisterType<UserService>().AsSelf();// 注入類自己,等價於.As<UserService>(); builder.RegisterType<ScoreManage>().AsImplementedInterfaces();//批量註冊,等價於.As<IEnglishScoreManage>().As<IMathematicsScoreManage>(); //2、Named註冊服務 //builder.RegisterType<ChineseScorePlusManage>().Named<IChineseScoreManage>(ChineseScoreEnum.ChineseScorePlus.ToString());// 一個接口與多個類型關聯 //builder.RegisterType<ChineseScoreManage>().Named<IChineseScoreManage>(ChineseScoreEnum.ChineseScore.ToString());// 一個接口與多個類型關聯 //3、Keyed註冊服務 builder.RegisterType<ChineseScorePlusManage>().Keyed<IChineseScoreManage>(ChineseScoreEnum.ChineseScorePlus);// 一個接口與多個類型關聯 builder.RegisterType<ChineseScoreManage>().Keyed<IChineseScoreManage>(ChineseScoreEnum.ChineseScore);// 一個接口與多個類型關聯 //泛型註冊,能夠經過容器返回List<T> 如:List<string>,List<int>等等 //builder.RegisterGeneric(typeof(List<>)).As(typeof(IList<>)).InstancePerLifetimeScope(); //生命週期 //builder.RegisterType<StudentService>().As<IStudentService>().InstancePerLifetimeScope(); //基於線程或者請求的單例..就是一個請求 或者一個線程 共用一個 //builder.RegisterType<StudentService>().As<IStudentService>().InstancePerDependency(); //服務對於每次請求都會返回單獨的實例 //builder.RegisterType<StudentService>().As<IStudentService>().SingleInstance(); //單例.. 整個項目公用一個 //builder.RegisterType<StudentService>().As<IStudentService>().InstancePerRequest(); //針對MVC的,或者說是ASP.NET的..每一個請求單例 builder.RegisterType<ServiceGetter>().As<IServiceGetter>();//用於一個接口與多個類型關聯 builder.RegisterControllers(Assembly.GetExecutingAssembly()).PropertiesAutowired();//屬性注入,未註冊將出現「沒有爲該對象定義無參數的構造函數。」 builder.RegisterType<TestDbContext>().As<IDbContext>().InstancePerLifetimeScope(); builder.RegisterGeneric(typeof(EfRepository<>)).As(typeof(IRepository<>)).InstancePerLifetimeScope();//泛型注入 //builder.RegisterFilterProvider(); //注入特性,特性裏面要用到相關的服務 IContainer container = builder.Build(); DependencyResolver.SetResolver(new AutofacDependencyResolver(container));//生成容器並提供給MVC } protected void Application_BeginRequest() { if (Request.IsLocal)//這裏是容許本地訪問啓動監控,可不寫 { MiniProfiler.Start(); } } protected void Application_EndRequest() { MiniProfiler.Stop(); } }
控制器
public class HomeController : Controller { private readonly IStudentService _studentService; private readonly ITeacherService _teacherService; private readonly IUserService _userService; public readonly UserService UserService; private readonly IEnglishScoreManage _englishScoreManage; private readonly IMathematicsScoreManage _mathematicsScoreManage; private IServiceGetter getter; public ICourseService CourseService { get; set; } private readonly IRepository<Student> _studentRrepository; public HomeController(IStudentService studentService, IUserService userService, ITeacherService teacherService, UserService userService1, IMathematicsScoreManage mathematicsScoreManage, IEnglishScoreManage englishScoreManage, IServiceGetter getter, IRepository<Student> studentRrepository) { _studentService = studentService; _userService = userService; _teacherService = teacherService; this.UserService = userService1; _mathematicsScoreManage = mathematicsScoreManage; _englishScoreManage = englishScoreManage; this.getter = getter; _studentRrepository = studentRrepository; } public ActionResult Index() { var name = ""; var student = _studentRrepository.GetById("4b900c95-7aac-4ae6-a122-287763856601"); if (student != null) { name = student.Name; } ViewBag.Name = _teacherService.GetName(); ViewBag.UserName1 = _userService.GetName(); ViewBag.UserName2 = UserService.GetName(); ViewBag.StudentName = _studentService.GetName() + "-" + name; ViewBag.CourseName = CourseService.GetName(); ViewBag.EnglishScore = _englishScoreManage.GetEnglishScore(); ViewBag.MathematicsScore = _mathematicsScoreManage.GetMathematicsScore(); //ViewBag.ChineseScore = getter.GetByName<IChineseScoreManage>(ChineseScoreEnum.ChineseScore.ToString()).GetScore(); //ViewBag.ChineseScorePlus = getter.GetByName<IChineseScoreManage>(ChineseScoreEnum.ChineseScorePlus.ToString()).GetScore(); ViewBag.ChineseScore = getter.GetByKey<ChineseScoreEnum, IChineseScoreManage>(ChineseScoreEnum.ChineseScore).GetScore(); ViewBag.ChineseScorePlus = getter.GetByKey<ChineseScoreEnum, IChineseScoreManage>(ChineseScoreEnum.ChineseScorePlus).GetScore(); return View(); } }
頁面
@{ ViewBag.Title = "Home Page"; } <div class="jumbotron"> <h1>ASP.NET</h1> </div> <div class="row"> <div class="col-md-4"> <h2>Teacher: @ViewBag.Name </h2> <p> CourseName: @ViewBag.CourseName </p> <p></p> </div> <div class="col-md-4"> <h2>User</h2> <p>接口注入:@ViewBag.UserName1</p> <p>類注入:@ViewBag.UserName2</p> </div> <div class="col-md-4"> <h2>Student: @ViewBag.StudentName</h2> <p>English:@ViewBag.EnglishScore</p> <p>Math: @ViewBag.MathematicsScore</p> <p>Chinese: @ViewBag.ChineseScore</p> <p>ChinesePlus:@ViewBag.ChineseScorePlus</p> </div> </div>
代碼下載:https://gitee.com/zmsofts/XinCunShanNianDaiMa/blob/master/EntityFrameworkExtension.rar
注意:codefirst開發,先遷移後才能使用
參考文章:
https://www.cnblogs.com/struggle999/p/6986903.html
https://www.cnblogs.com/gdsblog/p/6662987.html
https://www.cnblogs.com/kissdodog/p/3611799.html
https://www.cnblogs.com/fuyujian/p/4115474.html
http://www.cnblogs.com/tiantianle/category/779544.html