在這個架構中,我們使用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方法為其設定别名。