AutoFac的工作原理就是:注冊類並映射到接口,通過注入后返回相應實例化的類!
先來簡單介紹下Autofac的使用
1、通過Nuget或代碼安裝autofac
安裝autofac :install-package autofac
安裝對mvc4的支持:install -package autofac.mvc4
2、新建相應的類及接口,並在autofac中進行映射
2.1、新建接口 INewsHelper
1 namespace test.Interface 2 { 3 public interface INewsHelper 4 { 5 string GetNewInfo(int id); 6 } 7 }
2.2、新建類NewsHelper並繼承INewsHelper
1 namespace test.Helper 2 { 3 public class NewsHelper:INewsHelper 4 { 5 public string GetNewInfo(int id) 6 { 7 return "newshelper"; 8 } 9 } 10 }
2.3 新建類SubjectHelper並繼承INewsHelper
1 namespace test.Helper 2 { 3 public class SubjectHelper:INewsHelper 4 { 5 public string GetNewInfo(int id) 6 { 7 return "subjecthelper"; 8 } 9
10 } 11 }
2.4 在autofac中注冊並映射
1 namespace test 2 { 3 // 注意: 有關啟用 IIS6 或 IIS7 經典模式的說明, 4 // 請訪問 http://go.microsoft.com/?LinkId=9394801
5
6 public class MvcApplication : System.Web.HttpApplication 7 { 8 protected void Application_Start() 9 { 10 var builder = new ContainerBuilder(); 11 builder.RegisterType<CategoryHelper>().As<ICategoryHelper>().InstancePerHttpRequest(); 12
13 builder.RegisterType<NewsHelper>().Named<INewsHelper>("news"); 14 builder.RegisterType<SubjectHelper>().Named<INewsHelper>("subject"); 15
16 builder.RegisterControllers(Assembly.GetExecutingAssembly()); 17 var container = builder.Build(); 18 DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); 19
20
21 AreaRegistration.RegisterAllAreas(); 22 WebApiConfig.Register(GlobalConfiguration.Configuration); 23 FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 24 RouteConfig.RegisterRoutes(RouteTable.Routes); 25 BundleConfig.RegisterBundles(BundleTable.Bundles); 26 AuthConfig.RegisterAuth(); 27 } 28 } 29 }
3、新建ServiceGetter類及 IServiceGetter接口
3.1
1 namespace test.Interface 2 { 3 public interface IServiceGetter 4 { 5 T GetByName<T>(string name); 6 } 7 }
3.2
1 namespace test.Helper 2 { 3 public class ServiceGetter:IServiceGetter 4 { 5 public T GetByName<T>(string name) 6 { 7 return AutofacDependencyResolver.Current.RequestLifetimeScope.ResolveNamed<T>(name); 8 } 9 } 10 }
3.3 增加注冊
builder.RegisterType<ServiceGetter>().As<IServiceGetter>();
整個步驟3做了一件事,給中間件一個泛型的name,由中間件向autofac將相應的class的實例並返回,說白了就是干了下面這句代碼的事:
AutofacDependencyResolver.Current.RequestLifetimeScope.ResolveNamed<INewsHelper>(
"news"
);
4、通過構造函數進行注入
1 namespace test.Controllers 2 { 3 public class HomeController : Controller 4 { 5
6 private IServiceGetter getter; 7
8 public HomeController(IServiceGetter getter) 9 { 10
11 this.getter = getter; 12
13 } 14
15 public ActionResult Index() 16 { 17
18 ViewBag.Message = getter.GetByName<INewsHelper>("subject").GetNewInfo(1); 19 return View(); 20 } 21
22 } 23 }
Q:為什么沒有在HomeController的構造函數中直接就取回呢?
A:因為這個時候我們還不知道具體需要哪個實例,所以要在需要的時候通過getter再取回來。
這樣就完成了整個對於一個接口多個實現並定義多個Name的情況下,如何通過構造函數注入的方式來實現。
看下實際的效果:
情況1:
效果1:
情況2:
效果2: