//类ContainerBuilder中的方法: RegisterType<T>()//注册类型T AsImplementedInterfaces()//表示注册的类型,以接口的方式注册 Build()//创建一个容器
接口IContainer的方法:
Resolve<T>()//从容器中取出一个T类型的实例
1. 如何实现AsImplementedInterfaces()
builder.RegisterType<ListMovieFinder>().AsImplementedInterfaces(); //以类ListMovieFinder的接口IMovieFinder注册
那么我使用 Resolve<IMovieFinder>()要获取一个接口实例的时候,会返回一个ListMovieFinder的实例
2. 如何实现对同一个类型的注册,后面的覆盖前面的注册, 如源代码中:
builder.RegisterType<ListMovieFinder>().AsImplementedInterfaces();
builder.RegisterType<DBMovieFinder>().AsImplementedInterfaces();
后面的DBMovieFinder会覆盖掉ListMovieFinder的注册
这样,当我调用 Resolve<IMovieFinder>()要获取一个接口实例的时候,会返回一个DBMovieFinder的实例
protected void Application_Start() { var builder = new ContainerBuilder(); builder.RegisterControllers(typeof(MvcApplication).Assembly); var container = builder.Build(); DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); // Other MVC setup... }
1. 首先创建一个ContainerBuilder(它会稍后为我们提供一个容器,我们可以从中取出我们所需的对象实例)
2. 注册当前Assembly中的所有Controllers到Builder,这样Builder就获取了当前MVC项目中的所有Controller类型
3. 创建容器
4. 用AutofacDependencyResolver替换MVC默认的DependencyResolver
一、使用Entity Framework Code First, 写代码创建Student表
public class SchoolContext : DbContext { public SchoolContext() : base("DefaultConnection") { } public DbSet<Student> Students { get; set; } } [Table("Student")] public class Student { [Key] public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } }
首先我们可以创建一个接口:
public interface IStudentRepository { IEnumerable<Student> GetStudents(); }
然后, 创建一个集成这个接口的类,这个类并不访问数据库,但是提供我们开发页面所需的数据。
public class StubStudentRepository:IStudentRepository { public IEnumerable<Student> GetStudents() { return new[] { new Student {Id = 1, Name = "Sam", Age = 14} }; } }
public class HomeController : Controller { public ActionResult Index() { IStudentRepository studentRepository = new StubStudentRepository(); //IStudentRepository studentRepository = new StudentRepository();//注释掉访问数据层的代码,用Stub类代替 var students = studentRepository.GetStudents(); return View(students); } }
实例化
IStudentRepository studentRepository = new StubStudentRepository()
Autofac大显身手
public class HomeController : Controller { private readonly IStudentRepository _studentRepository; //由构造函数来提供Controller的依赖IStudentRepository public HomeController(IStudentRepository studentRepository) { _studentRepository = studentRepository; } public ActionResult Index() { var students = _studentRepository.GetStudents(); return View(students); } }
修改Global.asax,
public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { //Autofac初始化过程 var builder = new ContainerBuilder(); builder.RegisterControllers(typeof(MvcApplication).Assembly);//注册所有的Controller //开发环境下,使用Stub类 builder.RegisterAssemblyTypes(typeof (MvcApplication).Assembly).Where( t => t.Name.EndsWith("Repository") && t.Name.StartsWith("Stub")).AsImplementedInterfaces(); //发布环境下,使用真实的数据访问层 //builder.RegisterAssemblyTypes(typeof(MvcApplication).Assembly).Where( // t => t.Name.EndsWith("Repository")).AsImplementedInterfaces(); var container = builder.Build(); DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); //其它的初始化过程 ........ } }
所有的controller就都是使用Stub类的实例
//开发环境下,使用Stub类 builder.RegisterAssemblyTypes(typeof (MvcApplication).Assembly).Where( t => t.Name.EndsWith("Repository") && t.Name.StartsWith("Stub")).AsImplementedInterfaces();
private static void AutofacMvcRegister() { ContainerBuilder builder = new ContainerBuilder(); builder.RegisterGeneric(typeof(DbContextBase<>)).As(typeof(IDataRepository<>)); Type baseType = typeof(IDependency); Assembly[] assemblies = Assembly.GetExecutingAssembly().GetReferencedAssemblies() .Select(Assembly.Load).ToArray(); assemblies = assemblies.Union(new[] { Assembly.GetExecutingAssembly() }).ToArray(); builder.RegisterAssemblyTypes(assemblies) .Where(type => baseType.IsAssignableFrom(type) && !type.IsAbstract) .AsImplementedInterfaces().InstancePerLifetimeScope();//InstancePerLifetimeScope 保证生命周期基于请求 //无效 //builder.RegisterType<DefaultCacheAdapter>().PropertiesAutowired().As<ICacheStorage>(); builder.RegisterControllers(Assembly.GetExecutingAssembly()); builder.RegisterFilterProvider(); IContainer container = builder.Build(); DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); }
public class ListMovieFinder : IMovieFinder { public List<Movie> FindAll() { return new List<Movie> { new Movie { Name = "Die Hard.wmv" }, new Movie { Name = "My Name is John.MPG" } }; } } public interface IMovieFinder { List<Movie> FindAll(); } public class Movie { public string Name { get; set; } } public class MPGMovieLister { private readonly IMovieFinder _movieFinder; public MPGMovieLister(IMovieFinder movieFinder) { _movieFinder = movieFinder; } public Movie[] GetMPG() { var allMovies = _movieFinder.FindAll(); return allMovies.Where(m => m.Name.EndsWith(".MPG")).ToArray(); } } internal class Program { private static IContainer _container; private static void Main(string[] args) { InitIoC(); var lister = _container.Resolve<MPGMovieLister>(); foreach (var movie in lister.GetMPG()) { Console.WriteLine(movie.Name); } Console.Read(); } private static void InitIoC() { var builder = new ContainerBuilder(); builder.RegisterType<ListMovieFinder>().AsImplementedInterfaces(); //builder.RegisterType<DBMovieFinder>().AsImplementedInterfaces(); builder.RegisterType<MPGMovieLister>(); _container = builder.Build(); } }