天天看點

TinyFrame更新之四:IOC容器

在這個架構中,我們使用Autofac作為IOC容器,來實作控制反轉,依賴注入的目的。

在程式加載的時候,我需要将系統中所有用到的接口與之對應的實作進行裝載。由于使用者互動部分是在TinyFrame.Web中,并且請求入口是在Application_Start方法中,是以我在這裡進行了注入:

1:  private void RegisterDependency()      
2:          {      
3:              var builder = new ContainerBuilder();      
4:         
5:              builder.RegisterControllers(Assembly.GetExecutingAssembly());      
6:         
7:              builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>)).InstancePerHttpRequest();      
8:              builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerHttpRequest();      
9:         
10:              builder.RegisterType<BookContext>().As<IDbContext>().SingleInstance().PreserveExistingDefaults();      
11:              builder.RegisterType<ManagerRepository>().As<IManager>().InstancePerHttpRequest();      
12:              builder.RegisterType<BookLendRepository>().As<IBookLend>().InstancePerHttpRequest();      
13:              builder.RegisterType<BookPlaceRepository>().As<IBookPlace>().InstancePerHttpRequest();      
14:              builder.RegisterType<BookRepository>().As<IBook>().InstancePerHttpRequest();      
15:              builder.RegisterType<BookTypeRepository>().As<IBookType>().InstancePerHttpRequest();      
16:              builder.RegisterType<StudentRepository>().As<IStudent>().InstancePerHttpRequest();      
17:         
18:              builder.RegisterType<ManagerService>().As<IManagerService>().InstancePerHttpRequest();      
19:              builder.RegisterType<BookService>().As<IBookService>().InstancePerHttpRequest();      
20:         
21:              //builder.RegisterModule(new LogInjectionModule());      
22:              //注冊HttpContextBase,在PerRequestCacheManager中使用了。      
23:              //builder.RegisterModule(new AutofacWebTypesModule());      
24:         
25:              //HTTP context and other related stuff      
26:               builder.Register(c =>       
27:                   //register FakeHttpContext when HttpContext is not available      
28:                   new HttpContextWrapper(HttpContext.Current) as HttpContextBase)      
29:                   .As<HttpContextBase>()      
30:                   .InstancePerHttpRequest();      
31:               builder.Register(c => c.Resolve<HttpContextBase>().Request)      
32:                   .As<HttpRequestBase>()      
33:                   .InstancePerHttpRequest();      
34:               builder.Register(c => c.Resolve<HttpContextBase>().Response)      
35:                   .As<HttpResponseBase>()      
36:                   .InstancePerHttpRequest();      
37:               builder.Register(c => c.Resolve<HttpContextBase>().Server)      
38:                   .As<HttpServerUtilityBase>()      
39:                   .InstancePerHttpRequest();      
40:               builder.Register(c => c.Resolve<HttpContextBase>().Session)      
41:                   .As<HttpSessionStateBase>()      
42:                   .InstancePerHttpRequest();      
43:         
44:         
45:              builder.RegisterType<MemoryCacheManager>().As<ICacheManager>().Named<ICacheManager>("nop_cache_static").SingleInstance();      
46:              //由于預設會使用PerRequestCacheManager,并且使用者每請求一次資料,這個緩存都要重新建立一下。      
47:              //builder.RegisterType<PerRequestCacheManager>().As<ICacheManager>().Named<ICacheManager>("nop_cache_per_request").InstancePerHttpRequest();      
48:         
49:              builder.RegisterType<LoggerService>().As<ILoggerService>().InstancePerHttpRequest();      
50:         
51:              var container = builder.Build();      
52:              DependencyResolver.SetResolver(new AutofacDependencyResolver(container));      
53:         
54:          }      

這樣我們就能通過構造函數中定義的接口名稱,來直接使用其對象了。非常友善。

這裡我來解釋一下:

第3行:取得容器對象。

第5行:将系統中所有的controller進行注冊。

第7行:将系統中的泛型對象和對應的泛型接口進行注冊。

第8行:将系統中的對象和對應的接口進行注冊。

第10行:類型被多次注冊,後面的注冊會覆寫前面的,可以通過PreserveExistingDefaults設定預設注冊的值。

第45行:如果接口有多個實作,可以通過Named方法為其設定别名。