autofac版本:3.5.2

创建容器

var builder = new ContainerBuilder();

 

注册方式(这一部分的关注点在于给RegisterType、RegisterAssemblyTypes方法传递的参数,以及可以使用lambda表达式进行筛选

  1、泛型/类型注册,好处是很方便,但是缺点是:所注册的类型需要在当前项目中引用。使用了泛型注册,必须要类型明确。

builder.RegisterType<MSDService>().As<IService>();

  2、使用反射+类名字符串进行注册。使用这种注册方式进行注册的类,是可以不需要进行引用的,但是类所在的程序集需要事先被加载进来。(动态加载的时候可以使用这种方式)

builder.RegisterType(System.Type.GetType("MvcApplication1.Services.MSDService"));

  3、批量注册指定程序集中的所有非静态类。

builder.RegisterAssemblyTypes(Assembly.Load("MSD.BLL"));

    3.1、通常我们并不需要注册一个程序集中所有的类。所以可以使用lambda表达式进行过滤。

         Assembly assembly = Assembly.GetExecutingAssembly();
         builder.RegisterAssemblyTypes(assembly).Where(x => x.Namespace.Equals("MvcApplication1.Services"));//注册指定命名空间下的所有类型。
         builder.RegisterAssemblyTypes(assembly).InNamespaceOf<MSDService>();//注册MSDService类型所在的命名空间下的所有类型。
         builder.RegisterAssemblyTypes(assembly).Except<MSDService>();//不注册MSDService类。
         builder.RegisterAssemblyTypes(assembly).InNamespace("MvcApplication1.Services");//注册在指定命名空间下的所有类。

  4、Lambda注册。1~3所使用的注册方式都是通过构造函数直接new出了对象。如果想在注册之时为类做更多的事情可以通过lambda表达式的注册方式进行注册。

builder.Register(iComponentContext =>
            {
                MSDService af = new MSDService();
                if (af.Guid == null)
                    af.Guid = new System.Guid();//例子举的不好,但是大致的意思就是可以在注册之时,做其他的事情。
                return af;
            });

  5、模块注册(这种注册方式最方便,在多人同时协作一个项目的时候,如果使用上面的方式,难免会产生代码冲突,使用这种就可以避免这种情况,只要各自实现IModule接口就可以了)。

builder.RegisterAssemblyModules(assembly);//1、Module实现了IModule接口。2、RegisterAssemblyModules所注册的是实现了IModule接口的类。
builder.RegisterAssemblyModules<MSDService>(assembly);//只注册assembly程序集中继承自MSDService的模块。

 

解析已注册的类型

IContainer container = builder.Build();
IService msdService = container.Resolve<MSDService>();//如果事先没有对MSDService进行注册,那么Resolve时将会抛出异常。
IService msdService1 = container.ResolveOptional<MSDService>();//如果事先没有对MSDService进行注册,那么将返回一个null值。
IService msdService2 = null;
if (container.TryResolve(out msdService2))//类似于tryParse
{
   //如果解析成功
}
else
{
  //如果解析失败
}

当一个类有多个构造函数的情况下,autofac会使用哪一个构造函数?

使用尽可能最多参数的那个构造函数。详情:https://www.cnblogs.com/ancupofcoffee/p/5008469.html

可以通过传入指定参数,从而来指定使用哪一种构造函数来生成我们需要的类型。

var obj = container.Resolve<People>(new NamedParameter("guid", Guid.NewGuid()));

NamedParameter     根据参数名称进行匹配。
PositionalParameter      根据参数索引进行匹配,注意:起始索引为0。
TypedParameter      根据类型进行匹配,注意:传入多个相同类型的TypedParameter,所有该类型的参数都将采用第一个TypedParameter的值。
ResolvedParameter   接收两个Func参数,两个Func签名都接收两个相同的参数ParameterInfo和IComponmentContext,第一个参数为参数的信息,第二个参数还是当做IContainer使用就好了。第一个Func的返回值为bool,表明当前这个ResolvedParameter是否使用当前匹配到的参数,如果返回true,则会执行第二个Func;第二个Func返回一个object对象,用于填充构造参数值。

            container.Resolve<People>(new ResolvedParameter(
             x =>
             {

             },
             y =>
             {

             }
            ));

 

注入方式(这部分要关注点是:结合Person和Eating的构造函数或属性,使用不同的方法进行注册,以及在注册时,可能会碰到的问题)

    public class Person
    {
        public Eating eat = null;


        //public Person(Eating eat)//如果加上这个构造函数,那么就是属性注入。去掉了,就是自动属性注入
        //{
        //    this.eat = eat;
        //}

        public string Name { get; set; }


        public void Eating()
        {
            eat.DoSth();
        }
    }
Person.cs

相关文章:

  • 2021-11-12
  • 2021-07-21
  • 2021-11-23
  • 2021-08-24
  • 2021-06-03
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2022-03-08
  • 2022-12-23
  • 2021-11-26
  • 2022-12-23
  • 2021-08-24
  • 2021-06-27
相关资源
相似解决方案