AutoFac初探
#region RegisterType注册 var builder = new ContainerBuilder(); builder.RegisterType<DatabaseManager>(); builder.RegisterType<SqlDatabase>().As<IDatabase>();//通过AS可以让DatabaseManager类中通过构造函数依赖注入类型相应的接口。 using (var container = builder.Build()) { // var sqlIntance = container.Resolve<SqlDatabase>(); 【报错:】使用As方法会将原件默认的服务覆盖掉,所以无法用这种方式取得对象 var sqlIntance = container.Resolve<IDatabase>(); var manager = container.Resolve<DatabaseManager>(); manager.Search("Select * from User"); } #endregion #region 属性注入 /* * 属性注入 这是推荐的属性初始化方式. IComponentContext.ResolveOptional() 很方便: * builder.Register(c => new A(){ MyB = c.ResolveOptional<B>() }); * 或者, PropertiesAutowired() 这个方法也可以导致属性注入. * builder.RegisterType<X>().PropertiesAutowired(); */ #endregion #region 配置文件进行注册 //var builder = new ContainerBuilder(); //builder.RegisterType<DatabaseManager>(); //builder.RegisterModule(new ConfigurationSettingsReader("autofac")); //using (var container = builder.Build()) //{ // var manager = container.Resolve<DatabaseManager>(); // manager.Search("Select * form user"); //} /* * 这里通过ContainerBuilder方法RegisterType对DatabaseManager进行注册,当注册的类型在相应得到的容器中可以Resolve你的DatabaseManager实例。 builder.RegisterType<SqlDatabase>().As<IDatabase>();通过AS可以让DatabaseManager类中通过构造函数依赖注入类型相应的接口。 Build()方法生成一个对应的Container实例,这样,就可以通过Resolve解析到注册的类型实例。 */ #endregion #region 通过Register方法进行注册 //var builder = new ContainerBuilder(); //builder.RegisterModule(new ConfigurationSettingsReader("autofac")); //builder.Register(c => new DatabaseManager(c.Resolve<IDatabase>())); //构造函数注入,c是创建元件的容器 //using (var container = builder.Build()) //{ // var manager = container.Resolve<DatabaseManager>(); // manager.Search("Select * from User"); //} #endregion #region MyRegion //User user = new User { Id = 1, Name = "leepy" }; //var builder = new ContainerBuilder(); //builder.RegisterModule(new ConfigurationSettingsReader("autofac")); //builder.RegisterInstance(user).As<User>(); //已经存在的实例user,这时就不能再创造对象而是应该在容器中将它注册为实例,这种方法会确保系统中的单例实例最终转化为由容器托管的单例实例. //builder.Register(c => new DatabaseManager(c.Resolve<IDatabase>(), c.Resolve<User>())); //using (var container = builder.Build()) //{ // var manager = container.Resolve<DatabaseManager>(); // manager.Add("INSERT INTO USER ..."); //} #endregion #region 开放的泛型类型 /* * 开放的泛型类型 autofac支持开放的泛型类型.使用 RegisterGeneric() 这个方法: builder.RegisterGeneric(typeof(NHibernateRepository<>)) .As(typeof(IRepository<>)) .InstancePerLifetimeScope(); 当从容器中请求一个匹配的类型时,autofac会自动匹配一个等价的具体实现类型. // Autofac will return an NHibernateRepository<Task> var tasks = container.Resolve<IRepository<Task>>(); 注册一个具体的类型((e.g. IRepository<Person> )会覆盖掉上面的泛型注册. */ #endregion #region 【扫描组件】 var dataAccess = Assembly.GetExecutingAssembly(); builder.RegisterAssemblyTypes(dataAccess).Where(t => t.Name.EndsWith("Repository")).AsImplementedInterfaces(); //每个RegisterAssemblyTypes方法只能应用一套规则。如果有多套不同的集合要注册,那就有必要多次调用RegisterAssemblyTypes。 /* * 选择类型 RegisterAssemblyTypes接受程序集的集合。默认情况下,程序集中所有公共具体的类都会被注册。 如果想要过滤注册的类型,可以使用Where.向下面这样: Where(t => t.Name.EndsWith("Repository")) 如果想要排除某些类型,使用Except(): Except<MyUnwantedType>() 或者,自定义那些已经排除的类型的注册: Except<MyCustomisedType>(ct =>ct.As<ISpecial>().SingleInstance()) 多个过滤器可以同时使用,这时他们之间是AND的关系 * * * RegisterAssemblyTypes这个注册方法是注册单个方法的超集,所以类似As的方法也可以用在程序集中,例如 As<IRepository>() As和Named这两个方法额外的重载方法接受lambda表达式来决定服务会提供什么样的类型。 */ #endregion #region 【 Per Dependency】 /* Per Dependency 在其他容器中也称作瞬态或者工厂,使用Per Dependency作用域,服务对于每次请求都会返回单独的实例。 在没有指定其他参数的情况下,这是默认是作用域。 builder.RegisterType<X>(); or builder.RegisterType<X>().InstancePerDependency(); */ #endregion #region [Single Instance] /* Single Instance 使用Single Instance作用域,所有对父容器或者嵌套容器的请求都会返回同一个实例。 builder.RegisterType<X>().SingleInstance(); */ #endregion
************************************************分割线********************************************************************
//以IoC依赖注入方式创建对象 using (var container = RegisterContainer()) { container.Resolve<MemoChecker>().CheckNow(); Console.ReadKey(); }
/// <summary> /// 注册组件容器 /// </summary> /// <returns></returns> private static IContainer RegisterContainer() { //使用Autofac的依赖注入后的方式 //创建构造器 var builder = new ContainerBuilder(); //登记MemoChecker组件 builder.Register(c=>new MemoChecker( c.Resolve<IQueryable<Memo>>(), c.Resolve<IMemoDueNotifier >() )); //登记PrintingNotifier组件 builder.Register(c => new PrintingNotiffer(c.Resolve<TextWriter>())).As<IMemoDueNotifier>(); //注册实例对象 builder.RegisterInstance(memos); builder.RegisterInstance(Console.Out).As<TextWriter>().ExternallyOwned(); //检查依赖关系生成器 return builder.Build(); }
*************************************************分割线***************************************************************************
#region //var builer = new ContainerBuilder(); //builer.RegisterType<Dog>().As<IBehavior>(); //builer.RegisterType<Cat>().As<IBehavior>().PreserveExistingDefaults(); //PreserveExistingDefaults方法不会覆盖前面注册的服务 //var container = builer.Build(); //var dog = container.Resolve<IBehavior>(); //dog.Call(); #endregion #region 【按名字进行注册】 //var builder = new ContainerBuilder(); //builder.RegisterType<Dog>().Named<IBehavior>("a"); //builder.RegisterType<Cat>().Named<IBehavior>("b"); //var container = builder.Build(); //var dog = container.ResolveNamed<IBehavior>("a"); //var cat = container.ResolveNamed<IBehavior>("b"); //dog.Call(); //cat.Call(); #endregion #region 【注册服务按键来检索】 //var builder = new ContainerBuilder(); //builder.RegisterType<OnlineState>().Keyed<IDeviceState>(DeviceState.Online); //builder.RegisterType<OfflineState>().Keyed<IDeviceState>(DeviceState .Offline ); ////使用显示检索 //var container = builder.Build(); //var r = container.ResolveKeyed<IDeviceState>(DeviceState .Online); //这种方式不推荐 #endregion #region【自动装配】 //从容器中可用的服务中选择一个构造函数来创造对象,这个过程叫做自动装配。 ContainerBuilder builer= new ContainerBuilder(); builer.RegisterType<Dog>().UsingConstructor(typeof(int));//选择int类型的构造函数来进行实例化 #endregion
/// <summary> /// 根据索引获得实例 /// </summary> public class Modem : IHardwareDevice { IIndex<DeviceState, IDeviceState> _states; IDeviceState _currentState; public Modem(IIndex<DeviceState, IDeviceState> states) { _states = states; SwitchOn();//在SwitchOn方法中。使用索引从前面用DeviceState.Online做键注册的IDeviceState的实现。 } void SwitchOn() { _currentState = _states[DeviceState.Online]; } }
*************************************************分割线**********************************************************************
ContainerBuilder builder = new ContainerBuilder(); builder.RegisterControllers(Assembly.GetExecutingAssembly()); //1.builder.RegisterControllers注册了当前程序集内所有的Controller类。 builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).AsImplementedInterfaces();//2.builder.RegisterAssemblyTypes注册了当前程序集内的所有类。这里的AsImplementedInterfaces表示以接口的形式注册 builder.RegisterType<DLog>().As<ILog>(); //如果对象被多次注册,则以最后注册为准 // builder.RegisterType<DLog>().As<ILog>().PreserveExistingDefaults();//为了避免以最后一次注册为准,可以使用 PreserveExistingDefaults() 修饰符,这样就以第一次注册的为准 var container = builder.Build(); //创建一个容器 DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
*************************************************分割线************************************************************************
//注册整个程序集 public static void Run() { // var builder = new ContainerBuilder(); //var datadal = Assembly.Load("SqlServerDAL"); //builder.RegisterAssemblyTypes(datadal).Where(a => a.FullName.Contains("SqlServerDAL")).AsImplementedInterfaces(); //var databll = Assembly.Load("BLL"); //builder.RegisterAssemblyTypes(databll).Where(a => a.FullName.Contains("BLL")).AsImplementedInterfaces(); //builder.RegisterControllers(Assembly.GetExecutingAssembly()); // var contain = builder.Build(); // DependencyResolver.SetResolver(new AutofacDependencyResolver(contain)); }
//将Autofac容器中的实例注册到mvc自带DI容器中(这样才获取到每请求缓存的实例) DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
<!---配置文件注册时需要修改配置文件---> <configuration> <configSections> <section name="autofac" type="Autofac.Configuration.SectionHandler, Autofac.Configuration"/> </configSections> <autofac defaultAssembly="AutofacDemo"> <components> <component type="AutofacDemo.SqlDatabase, AutofacDemo" service="AutofacDemo.IDatabase" /> </components> </autofac> </configuration>