AutoFac在项目中应用的体会
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: