zoukankan      html  css  js  c++  java
  • autofac基础知识

    参考网址:https://www.cnblogs.com/Xieyiincuit/p/14386732.html

     前言:使用Autofac这一款IOC容器来替代Asp.Net Core自带的容器。

    1. Autofac基础使用

    准备工作:

    编写一个抽象接口和一个具体实现类分别为:

    复制代码
    public interface ITestServiceA
    {
        void Show();
    }
    
    
    public class TestServiceA : ITestServiceA
    {
        public TestServiceA()
        {
            Console.WriteLine($"{this.GetType().Name} was Constructed");
        }
        public void Show()
        {
            Console.WriteLine("AAA");
        }
    }
    复制代码

      (1) 管理NuGet程序包,下载安装【Autofac】。

          

        (2) 在Startup.cs中的ConfigureServices注册服务。

    • 创建 ContainerBuilder.
    • 注册组件.
    • 创建容器,将其保存以备后续使用.
    • 应用执行阶段...
    • 从容器中创建一个生命周期.
    • 在此生命周期作用域内解析组件实例.
    复制代码
    //创建ContainerBuilder
    ContainerBuilder containerBuilder = new ContainerBuilder();
    
    //注册组件告诉容器哪些 组件 暴露了哪些 服务
    //RegisterType注册的组件必须是个具体的类型 组件可以暴露抽象类和接口作为 服务
    containerBuilder.RegisterType<TestServiceA>().As<ITestServiceA>();
    
    //创建容器
    IContainer container = containerBuilder.Build();
    
    //从容器中获取一个生命周期
    using (var scope = container.BeginLifetimeScope())
    {
        //解析组件实例
        var service = scope.Resolve<ITestServiceA>();
    
        //调用服务
        service.Show();
    }
    复制代码

    2. Autofac注入方式:

    • 构造函数注入(默认支持构造函数注入)
    复制代码
    var builder = new ContainerBuilder();
    builder.RegisterType<TestServiceA>().As<ITestServiceA>();
    var container = builder.Build();
    
    using var scope = container.BeginLifetimeScope();
    var testServiceA = scope.Resolve<ITestServiceA>();
    testServiceA.Show();
    复制代码

      在控制器中注入:

    public HomeController(ITestServiceA serviceA, ILogger<HomeController> logger)
    {
        _serviceA = serviceA;
        _logger = logger;
    }

      需要注意的点是当我们的某一个服务在内部引用了其他的服务的情况下,我们需要也注册该服务引用的服务。

      如我在之前的准备工作中新增两个服务ITestServiceB,ITestServiceC。而服务C需要服务B的注入。

    复制代码
    public interface ITestServiceB
    {
        void Show();
    }
    
    public interface ITestServiceC
    {
        void Show();
    }
    
    public class TestServiceB : ITestServiceB
    {
        public TestServiceB()
        {
            Console.WriteLine($"{this.GetType().Name} was Constructed");
        }
        public void Show()
        {
            Console.WriteLine("BBB");
        }
    }
    
    public class TestServiceC : ITestServiceC
    {
        public TestServiceC(ITestServiceB iTestServiceB)
        {
            Console.WriteLine($"{this.GetType().Name} was Constructed");
        }
        public void Show()
        {
            Console.WriteLine("CCC");
        }
    }
    复制代码

      这个时候我们想要使用解析ITestServiceC,则在注册服务时,需要注册ITestServiceB。否则将会出现异常。

    复制代码
    var builder = new ContainerBuilder();
    builder.RegisterType<TestServiceB>().As<ITestServiceB>();
    builder.RegisterType<TestServiceC>().As<ITestServiceC>();
    var container = builder.Build();
    
    using var scope = container.BeginLifetimeScope();
    var testServiceC = scope.Resolve<ITestServiceC>();
    testServiceC.Show();
    复制代码

    • 属性注入

      新增一个服务ITestServiceD。其中有三个公共属性需要注入。

    复制代码
    public class TestServiceD : ITestServiceD
    {
        public ITestServiceA TestServiceA { get; set; }
        public ITestServiceB TestServiceB { get; set; }
        public ITestServiceC TestServiceC { get; set; }
    
        public TestServiceD()
        {
            Console.WriteLine($"{this.GetType().Name} was Constructed");
        }
    
        public void Show()
        {
            TestServiceC.Show();
            Console.WriteLine("DDD");
        }
    }
    复制代码

      注入方式为调用.PropertiesAutowired()方法即可。

    复制代码
    var builder = new ContainerBuilder();
    
    builder.RegisterType<TestServiceA>().As<ITestServiceA>();
    builder.RegisterType<TestServiceB>().As<ITestServiceB>();
    builder.RegisterType<TestServiceC>().As<ITestServiceC>();
    builder.RegisterType<TestServiceD>().As<ITestServiceD>().PropertiesAutowired();
    var container = builder.Build();
    using var scope = container.BeginLifetimeScope();
    var testServiceD = scope.Resolve<ITestServiceD>();
    testServiceD.Show();
    复制代码
    • 方法注入

      对ITestServiceB进行修改,增加一个方法注入ITestServiceA.

    复制代码
    public class TestServiceB : ITestServiceB
    {
        public ITestServiceA TestServiceA { get; set; }
    
        public void SetService(ITestServiceA serviceA)
        {
            TestServiceA = serviceA;
        }
    
        public TestServiceB()
        {
            Console.WriteLine($"{this.GetType().Name} was Constructed");
        }
        public void Show()
        {
            TestServiceA.Show();
            Console.WriteLine("BBB");
        }
    }
    复制代码

      想要调用一个方法来设置组件上的某个值, 最简单的方法是使用 lambda表达式组件 然后在activator中进行正确的方法调用:

    复制代码
    ContainerBuilder containerBuilder = new ContainerBuilder();
    containerBuilder.RegisterType<TestServiceA>().As<ITestServiceA>();
    containerBuilder.Register(c =>
    {
        //创建变量来返回注册结果
        var result = new TestServiceB();
        
        //获取方法注入需要的服务
        var dep = c.Resolve<ITestServiceA>();
        
        //调用方法注入
        result.SetService(dep); 
        return result;
    });
    
    IContainer container = containerBuilder.Build();
    ITestServiceB serviceB = container.Resolve<TestServiceB>(); serviceB.Show();
  • 相关阅读:
    Max关闭WPF
    InstallShield安装过程介绍
    InstallShield相关资料整理
    .net reflection的一点研究
    (转)VMware增加磁盘容量方法
    领域驱动设计《读书笔记》
    《领域驱动设计C#2008实现》读书笔记
    深入研究c++对象模型
    <转载>com之包容聚合
    基于插件开发的架构研究
  • 原文地址:https://www.cnblogs.com/bruce1992/p/15273099.html
Copyright © 2011-2022 走看看