zoukankan      html  css  js  c++  java
  • Autofac

    属性注入不同于通过构造函数方式传入参数. 这里是通过注入的方式, 在类创建完毕之后, 资源释放之前, 给属性赋值.

    这里, 我重新弄一些类来演示这一篇吧.

    public class ClassA
    {
        private readonly ClassB b;
    
        public ClassA(ClassB b)
        {
            this.b = b;
        }
    
        public void Show()
        {
            Console.WriteLine("I am ClassA's instance !");
        }
    }
    
    public class ClassB
    {
        public ClassA A { get; set; }
    
        public void Show()
        {
            Console.WriteLine("I am ClassB's instance !");
        }
    
    }
    
    public class ClassC
    {
       public string Name { get; set; }
    public ClassD D { get; set; } public void Show() { Console.WriteLine("I am ClassC's instance !" + Name); } } public class ClassD { public void Show() { Console.WriteLine("I am ClassD's instance !"); } }

    1. 一般方法

    var builder = new ContainerBuilder();
    
    builder.Register(n => new ClassC { D = n.Resolve<ClassD>(), Name = "Sniper"  });
    builder.RegisterType<ClassD>();
    
    var container = builder.Build();
    
    var c = container.Resolve<ClassC>();
    c.Show();
    c.D.Show();

    这种方法, 不止可以注入属性, 还可以给字段赋值

    2. 反射的方式

    var builder = new ContainerBuilder();
    
    builder.RegisterType<ClassD>();
    var s = builder.RegisterType<ClassC>().PropertiesAutowired();
    
    var container = builder.Build();
    
    var c = container.Resolve<ClassC>();
    c.Show();
    c.D.Show();

    这里需要注意一点, 由于ClassC中有ClassD格式的属性, 所以ClassD也必须要注册一下. 为什么呢? 来看一下源码

    PropertiesAutowired()方法里面, 主要就是调用上图中的方法. 会通过反射的方式获取属性, 然后也是通过Resolve的方式来获取属性的值.

    注:

      仔细观察ClassA和ClassB, 可以发现, 他们循环依赖了, 那么如果我要得到ClassB, 怎么办? 尝试下第一种方法, 你会发现, 我去, 报错了.

      尝试下第二种方法, 还是报错. 那怎么办呢? 

    var builder = new ContainerBuilder();
    
    builder.RegisterType<ClassB>().PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies).SingleInstance();
    builder.Register(n=>new ClassA(n.Resolve<ClassB>()));
    
    var container = builder.Build();
    
    var b = container.Resolve<ClassB>();
    b.Show();
    b.A.Show();

    还是通过反射的方式, 只不过要注意一下, 传入参数和SingleInstance, 不加, 都会报错的.

    3. 通过名称

    var builder = new ContainerBuilder();
    
    var s = builder.RegisterType<ClassC>().WithProperty("D", new ClassD());
    
    var container = builder.Build();
    
    var c = container.Resolve<ClassC>();
    c.Show();
    c.D.Show();

    通过属性名称, 直接new一个实例给他

    4. OnActivating/OnActivated 方式

    此方法的执行时机, 是构造函数创建结束之后, 资源释放之前, 所以在此期间也可以实现

    var builder = new ContainerBuilder();
    
    builder.RegisterType<ClassC>().OnActivating(e => e.Instance.D = e.Context.Resolve<ClassD>());
    builder.RegisterType<ClassD>();
    
    var container = builder.Build();
    
    var c = container.Resolve<ClassC>();
    c.Show();
    c.D.Show();

    这里的 OnActivating 也可换成 OnActivated . 实现这里的场景, 是能得到一样的结果的.

     参考:

       AutoFac使用方法总结

       Autofac 组件、服务、自动装配 《第二篇》

       Autofac文档

  • 相关阅读:
    安卓平台下ARM Mali OpenCL编程-GPU信息检测(转)
    Android 常用的性能分析工具详解:GPU呈现模式, TraceView, Systrace, HirearchyViewer(转)
    windows配置meld
    nginx的学习材料
    nginx+lua组合的web框架
    [转] Linux下防火墙iptables用法规则详及其防火墙配置
    转:关于知乎音视频学习入门的解答
    转: 在创业公司使用C++
    【转】 消息队列设计精要
    转: __asm__ __volatile__内嵌汇编用法简述
  • 原文地址:https://www.cnblogs.com/elvinle/p/6232365.html
Copyright © 2011-2022 走看看