天天看点

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方法为其设置别名。