首页 > 编程语言 >C# Autofac 构造函数注入,属性注入,方法注入

C# Autofac 构造函数注入,属性注入,方法注入

时间:2023-03-26 11:04:48浏览次数:35  
标签:Autofac RegisterType builder cat say void 注入 public 构造函数

十年河东,十年河西,莫欺少年穷。

学无止境,精益求精。

新建一个控制台应用程序,如下构造:

C# Autofac 构造函数注入,属性注入,方法注入_构造函数

 MyAutoFac层引入autofac 版本 V6.5

接口层如下:

namespace MyInterface
{
    public interface IPerson
    {
        void say();
        void PlayerWithDog();
        void PlayerWithCat();
        void PlayerWithPig();
    }
    public interface IDog
    {
        void say();
    }

    public interface ICat
    {
        void say();
    }
    public interface IPig
    {
        void say();
    } 
}

服务层如下:

namespace MyService
{
    public class PersonService : IPerson
    {
        private readonly IDog dog;
        private readonly ICat cat;
        private readonly IPig pig;
        public PersonService(IDog dog)
        {
            this.dog = dog;
        }
        public PersonService(IDog dog, ICat cat)
        {
            this.dog = dog;
            this.cat = cat;
        }
        public PersonService(IDog dog,  IPig pig, ICat cat)
        {
            this.pig = pig;
            this.cat = cat;
        }
        public void say()
        {
            Console.WriteLine("你好");
        }

        public void PlayerWithDog()
        {
            if (dog == null)
            {
                return;
            }
            Console.WriteLine("人在跳绳,狗在叫:");
            this.dog.say();
        }

        public void PlayerWithCat()
        {
            if (cat == null)
            {
                return;
            }
            Console.WriteLine("人在跳绳,猫在叫:");
            this.cat.say();
        }
        public void PlayerWithPig()
        {
            if (pig == null)
            {
                return;
            }
            Console.WriteLine("人在跳绳,猪在叫:");
            this.pig.say();
        }
    }

    public class DogService : IDog
    {
        public void say()
        {
            Console.WriteLine("汪汪汪");
        }
    }

    public class CatService : ICat
    {
        public void say()
        {
            Console.WriteLine("喵喵喵");
        }
    }

    public class PigService : IPig
    {
        public void say()
        {
            Console.WriteLine("哼哼哼");
        }
    }
}

1、构造函数注入

1.1、构造函数默认注入

引入一个构造函数参数

{
    //构造函数默认注入
    ContainerBuilder builder = new ContainerBuilder();
    builder.RegisterType<DogService>().As<IDog>();
    builder.RegisterType<PersonService>().As<IPerson>();
    IContainer container = builder.Build();
    var p = container.Resolve<IPerson>();
    p.say();
    p.PlayerWithDog();
}

上述代码中先通过RegisterType引入IDog,后引入IPerson,会执行PersionService中有一个IDog作为参数的构造函数

调式如下:

C# Autofac 构造函数注入,属性注入,方法注入_修饰符_02


 

将上述代码修改如下:

引入三个构造函数参数

{
    //构造函数默认注入
    ContainerBuilder builder = new ContainerBuilder();
    builder.RegisterType<DogService>().As<IDog>();
    builder.RegisterType<PigService>().As<IPig>();
    builder.RegisterType<CatService>().As<ICat>();
    builder.RegisterType<PersonService>().As<IPerson>();
    IContainer container = builder.Build();
    var p = container.Resolve<IPerson>();
    p.say();
    p.PlayerWithDog();
}

通过RegisterType引入了IDog、ICat、IPig,因此会走具有三个参数的构造函数

调试如下:

C# Autofac 构造函数注入,属性注入,方法注入_构造函数_03


 

将代码继续修改如下:

 通过反射,加载所有接口及其实现类

{
    //通过程序集加载
    ContainerBuilder builder = new ContainerBuilder();
    Assembly assemblyInterface = Assembly.LoadFrom("MyInterface.dll");
    Assembly assemblyService = Assembly.LoadFrom("MyService.dll");
    builder.RegisterAssemblyTypes(assemblyInterface, assemblyService).AsImplementedInterfaces();
    IContainer container = builder.Build();
    //PersonService 会执行参数多的构造函数
    var p = container.Resolve<IPerson>();
    p.PlayerWithDog(); p.PlayerWithCat(); p.PlayerWithPig();
}

调式如下:

C# Autofac 构造函数注入,属性注入,方法注入_构造函数_03

这里需要说明的是,如果构造函数中有相同参数个数的构造函数,AutoFac会报错,他就不知道该执行哪个构造函数了。

 1.2、通过UsingConstructor方法指定要执行的构造函数

代码如下:

{
    //注册一个普通类
    ContainerBuilder builder = new ContainerBuilder();
    builder.RegisterType<DogService>().As<IDog>();
    builder.RegisterType<CatService>().As<ICat>();
    builder.RegisterType<PersonService>().As<IPerson>().UsingConstructor(typeof(IDog), typeof(ICat));
    IContainer container = builder.Build();
    var p = container.Resolve<IPerson>();
    p.say();
    p.PlayerWithDog();
    p.PlayerWithCat();
}

C# Autofac 构造函数注入,属性注入,方法注入_修饰符_05

 调式如下

C# Autofac 构造函数注入,属性注入,方法注入_构造函数_06

 2、属性注入

2.1、PropertiesAutowired()方法属性注入

使用PropertiesAutowired()方法支持属性注入

新增接口及实现类如下:

接口

/// <summary>
    /// 动物接口
    /// </summary>
    public interface IAnimal
    {
        void say();
    }

实现类【实现类中有三个属性】

public class AnimalService : IAnimal
    {

        /// <summary>
        /// 属性注入时,修饰符必须为Public
        /// </summary>
        /// 
        public IDog dog { get; set; }
        /// <summary>
        /// 属性注入时,修饰符必须为Public
        /// </summary>
        /// 
        public ICat cat { get; set; }
        /// <summary>
        /// 属性注入时,修饰符必须为Public
        /// </summary>
        public IPig pig { get; set; }

        public void say()
        {
            if (this.dog != null)
            {
                this.dog.say();
            }
            if (this.cat != null)
            {
                this.cat.say();
            }
            if (this.pig != null)
            {
                this.pig.say();
            }
        }
    }

 

代码如下

{
    //属性注入
    ContainerBuilder builder = new ContainerBuilder();
    builder.RegisterType<DogService>().As<IDog>();
    builder.RegisterType<CatService>().As<ICat>();
    builder.RegisterType<PigService>().As<IPig>();
    builder.RegisterType<AnimalService>().As<IAnimal>().PropertiesAutowired();
    IContainer container = builder.Build();
    var p = container.Resolve<IAnimal>();
    p.say();
}

C# Autofac 构造函数注入,属性注入,方法注入_构造函数_07

 调式如下:

C# Autofac 构造函数注入,属性注入,方法注入_修饰符_08

 2.2、属性注入选择器

新建属性类及属性选择器如下:

namespace MyIocAutoProperties
{
    [AttributeUsage(AttributeTargets.Property)]
    public class IocSelectAttribute: Attribute
    {

    }

    public class IoctAttributeSelector : IPropertySelector
    {
        public bool InjectProperty(PropertyInfo propertyInfo, object instance)
        {
            return propertyInfo.CustomAttributes.Any(A => A.AttributeType == typeof(IocSelectAttribute));
        }
    }
}

修改如下:

public class AnimalService : IAnimal
    { 
        /// <summary>
        /// 属性注入时,修饰符必须为Public
        /// </summary>
        /// 
        [IocSelect]
        public IDog dog { get; set; }
        /// <summary>
        /// 属性注入时,修饰符必须为Public
        /// </summary>
        /// 
        [IocSelect]
        public ICat cat { get; set; }
        /// <summary>
        /// 属性注入时,修饰符必须为Public
        /// </summary>
        public IPig pig { get; set; }

        public void say()
        {
            if (this.dog != null)
            {
                this.dog.say();
            }
            if (this.cat != null)
            {
                this.cat.say();
            }
            if (this.pig != null)
            {
                this.pig.say();
            }
        }
    }

View Code

C# Autofac 构造函数注入,属性注入,方法注入_构造函数_09

 

 代码如下:

{
    //属性注入
    ContainerBuilder builder = new ContainerBuilder();
    builder.RegisterType<DogService>().As<IDog>();
    builder.RegisterType<CatService>().As<ICat>();
    builder.RegisterType<PigService>().As<IPig>();
    builder.RegisterType<AnimalService>().As<IAnimal>().PropertiesAutowired(new IoctAttributeSelector());
    IContainer container = builder.Build();
    var p = container.Resolve<IAnimal>();
    p.say();
}

View Code

C# Autofac 构造函数注入,属性注入,方法注入_属性注入_10

 

 吊事如下:

C# Autofac 构造函数注入,属性注入,方法注入_属性注入_11

 3、方法注入

所谓方法注入是指:在接口对象构造后,自动调用对象的某个方法

在接口中增加一个Eat方法

/// <summary>
    /// 动物接口
    /// </summary>
    public interface IAnimal
    {
        void say();
        void eat(ICat cat);
    }

实现类如下:

public class AnimalService : IAnimal
    { 
        /// <summary>
        /// 属性注入时,修饰符必须为Public
        /// </summary>
        ///  
        public IDog dog { get; set; }
        /// <summary>
        /// 属性注入时,修饰符必须为Public
        /// </summary>
        ///  
        public ICat cat { get; set; }
        /// <summary>
        /// 属性注入时,修饰符必须为Public
        /// </summary>
        public IPig pig { get; set; }

        public void say()
        {
            if (this.dog != null)
            {
                this.dog.say();
            }
            if (this.cat != null)
            {
                this.cat.say();
            }
            if (this.pig != null)
            {
                this.pig.say();
            }
        }

        public void  eat(ICat cat)
        {
            Console.WriteLine("方法注入:在构建IAnimal对象时,触发eat方法执行");
        }
    }

View Code

代码如下:

{
    //方法注入
    ContainerBuilder builder = new ContainerBuilder(); 
    builder.RegisterType<CatService>().As<ICat>();
    builder.RegisterType<AnimalService>().As<IAnimal>().OnActivated(Activator =>
    {
        var cat = Activator.Context.Resolve<ICat>();
        Activator.Instance.eat(cat);
    }); 
    IContainer container = builder.Build();
    //构建IAnimal对象,触发上述eat方法执行
    container.Resolve<IAnimal>();
}

程序将在 container.Resolve<IAnimal>(); 之后,执行eat方法

调式如下:

C# Autofac 构造函数注入,属性注入,方法注入_修饰符_12

 

 4、单抽象,多实现

如下案例

/// <summary>
    /// 动物接口
    /// </summary>
    public interface IAnimal
    {
        void say(); 
    }

多个实现类继承该接口

public class DogService : IAnimal
    {
        public void say()
        {
            Console.WriteLine("汪汪汪");
        }
    }

    public class CatService : IAnimal
    {
        public void say()
        {
            Console.WriteLine("喵喵喵");
        }
    }

    public class PigService : IAnimal
    {
        public void say()
        {
            Console.WriteLine("哼哼哼");
        }
    }

View Code

先看如下代码:

{
    //单抽象多继承
    ContainerBuilder builder = new ContainerBuilder();
    builder.RegisterType<DogService>().As<IAnimal>();
    builder.RegisterType<CatService>().As<IAnimal>();
    builder.RegisterType<PigService>().As<IAnimal>();
    IContainer container = builder.Build(); 
    var p = container.Resolve<IAnimal>();
    var ps = container.Resolve<IEnumerable<IAnimal>>(); 
}

p为最后注册的对象

C# Autofac 构造函数注入,属性注入,方法注入_构造函数_13

 

 ps为所有实现类对象集合

C# Autofac 构造函数注入,属性注入,方法注入_构造函数_14

 

 那么问题来了,我们该如何获取到指定的对象呢?

通过加入key来识别即可,如下

{
    //单抽象多继承
    ContainerBuilder builder = new ContainerBuilder();
    builder.RegisterType<DogService>().Keyed<IAnimal>("dog");
    builder.RegisterType<CatService>().Keyed<IAnimal>("cat");
    builder.RegisterType<PigService>().Keyed<IAnimal>("pig");
    IContainer container = builder.Build();
    //这里是狗
    var dog = container.ResolveKeyed<IAnimal>("dog");
    //这里是猫
    var cat = container.ResolveKeyed<IAnimal>("cat");
    //这里是猪
    var pig = container.ResolveKeyed<IAnimal>("pig"); 
}

自此结束

@天才卧龙的博客



标签:Autofac,RegisterType,builder,cat,say,void,注入,public,构造函数
From: https://blog.51cto.com/u_15316082/6149927

相关文章

  • C# Autofac简单用法
    十年河东,十年河西,莫欺少年穷学无止境,精益求精新建一个控制台程序,如下 MyAutoFac项目引用NugetautofacV6.5版本新建如下接口:publicinterface动物{void......
  • 《渗透测试》WEB攻防-Python考点&CTF与CMS-SSTI模版注入&PYC反编译 2022 Day23
    1     1PY反编译-PYC编译文件反编译源码1.1pyc文件是py文件编译后生成的字节码文件(bytecode),pyc文件经过python解释器最终会生成机器码运行。因此pyc文......
  • DC-8(sql注入漏洞)
    信息收集扫描ip和端口:通过nmap扫描ip和端口发现:ip为192.168.6.152,开放端口号为80和22扫描目录:dirb和desearch,发现了疑似登录界面查看框架:Drupal7漏洞扫描:searchsploitDru......
  • MyBatisPlus中全局Sql注入器应用_逻辑删除使用
    什么是逻辑删除假删除、逻辑删除,并不会真正的从数据库中将数据删除掉,而是将当前被删除的这条数据的一个逻辑字段置为删除状态。实现全局配置注入LogicSqlInjector打开项目的......
  • MYSQL注入流程
    一、判断注入点(与数据库有交互的地方)浏览网站各个地方-->查找有可控参数的地方(特别注意url)并观察网站页面变化情况  根据参数传输方式传输的不同,可以把SQL注入分为GE......
  • day11-SpringBoot中注入Servlet&Filter&Listener
    SpringBoot中注入Servlet&Filter&Listener1.基本介绍文档:SpringBoot中注入Servlet&Filter&Listener考虑到实际开发业务非常复杂和兼容问题,SpringBoot支持将Servlet、......
  • Spring依赖注入的方式
    ①变量注入:注入方式简单简洁,没有多余代码。但可能会导致循环依赖。②构造器注入:避免循环依赖。但注入过多会导致代码臃肿。③setter方法注入:注入的依赖可以为NULL。使用......
  • DLL注入-Windows消息钩取
    0x01钩子钩子,英文Hook,泛指钓取所需东西而使用的一切工具。后来延伸为“偷看或截取信息时所用的手段或工具”。挂钩:为了偷看或截取来往信息而在中间设置岗哨的行为钩取......
  • 会话管理机制、SQL注入攻击
    会话管理机制会话管理概述绝大多数Web应用程序中,回话管理机制是一个基本的安全组件回话管理在应用程序执行登录功能时显得特别重要因为,它可以在用户通过请求提交他们的......
  • CRLF注入
    CRLF注入【漏洞介绍】CRLF注入可以将一条合法日志拆分成两条,甚至多条,使得日志内容令人误解,对日志审计造成很大的困难。或者将HTTP消息头注入恶意换行,造成会话固定、不安全......