首页 > Web开发 > 详细

asp.net core3.1 实战开发(autofact的使用替换框架的IOC实现AOP)

时间:2020-05-13 09:21:07      阅读:141      评论:0      收藏:0      [点我收藏+]
原文:asp.net core3.1 实战开发(autofact的使用替换框架的IOC实现AOP)

原有core 3.1内置了ioc容器和DI注入,有个缺点就算不能够实现AOP,所以使用第三方autofact来代替原有的容器

一:原有core 3.1的容器使用方法

配置服务

public void ConfigureServices(IServiceCollection services)
{
    services.AddSession();
    services.AddControllersWithViews();
    //只能构造函数注入--需要一个构造函数超集
    services.AddTransient<ITestServiceA, TestServiceA>();//瞬时
    services.AddSingleton<ITestServiceB, TestServiceB>();//单例
    services.AddScoped<ITestServiceC, TestServiceC>();//作用域单例--一次请求一个实例
    //作用域其实依赖于ServiceProvider(这个自身是根据请求的),跟多线程没关系
    services.AddTransient<ITestServiceD, TestServiceD>();
    services.AddTransient<ITestServiceE, TestServiceE>();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

构造函数注入

public class SecondController : Controller
{
    private readonly ILogger<SecondController> _logger;
    private readonly ILoggerFactory _loggerFactory;
    private readonly ITestServiceA _iTestServiceA;
    private readonly ITestServiceB _iTestServiceB;
    private readonly ITestServiceC _iTestServiceC;
    private readonly ITestServiceD _iTestServiceD;
    private readonly ITestServiceE _iTestServiceE;
    private readonly IServiceProvider _iServiceProvider;
    /// <summary>
    /// 来自DI依赖注入---构造函数注入---构造A对象依赖B对象,自动初始化B对象传入
    /// 
    /// 有个容器,负责构造SecondController(反射)--反射构造函数--需要B--再构造B---然后再构造A
    /// </summary>
    /// <param name="logger"></param>
    /// <param name="loggerFactory"></param>
    public SecondController(ILogger<SecondController> logger,
        ILoggerFactory loggerFactory
        , ITestServiceA testServiceA
        , ITestServiceB testServiceB
        , ITestServiceC testServiceC
        , ITestServiceD testServiceD
        , ITestServiceE testServiceE
        , IServiceProvider serviceProvider)
    //一次注入这么多,可能用不上,能不能我自己生成? 不建议,
    //1 大部分对象生成其实很快,且不占资源--特殊可以自己控制
    //2 对象生命周期不同,注入的是跟controller的,action是跟方法的
    {
        this._logger = logger;
        this._loggerFactory = loggerFactory;
        this._iTestServiceA = testServiceA;
        this._iTestServiceB = testServiceB;
        this._iTestServiceC = testServiceC;
        this._iTestServiceD = testServiceD;
        this._iTestServiceE = testServiceE;
        this._iServiceProvider = serviceProvider;
    }
    /// <summary>
    /// 纯属测试 毫无意义
    /// </summary>
    private static ITestServiceC _iTestServiceCStatic = null;
    private static ITestServiceB _iTestServiceBStatic = null;

    public IActionResult Index()
    {
        //ITestServiceA testServiceA = new TestServiceA();
        this._logger.LogWarning("This is SecondController Index");

        var c = this._iServiceProvider.GetService<ITestServiceC>();
        Console.WriteLine($"cc {object.ReferenceEquals(this._iTestServiceC, c)}");//T/F

        if (_iTestServiceCStatic == null)
        {
            _iTestServiceCStatic = _iTestServiceC;
        }
        else
        {
            Console.WriteLine($"C&C {object.ReferenceEquals(this._iTestServiceC, _iTestServiceCStatic)}");//两次不同的请求  //T/F
        }

        if (_iTestServiceBStatic == null)
        {
            _iTestServiceBStatic = _iTestServiceB;
        }
        else
        {
            Console.WriteLine($"B&B:{object.ReferenceEquals(this._iTestServiceB, _iTestServiceBStatic)}");//两次不同的请求  //T/F
        }


        this._iTestServiceA.Show();
        this._iTestServiceB.Show();
        this._iTestServiceC.Show();
        this._iTestServiceD.Show();
        this._iTestServiceE.Show();
        return View();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79

二:autofac的容器使用方法

首先nuget引入:Autofac.Extensions.Depend
Profram中加入如下代码

public static IHostBuilder CreateHostBuilder(string[] args) =>
  Host.CreateDefaultBuilder(args)//就是指定kestrel
                                 //.ConfigureLogging(loggingBuilder =>
                                 //    {
                                 //        loggingBuilder.AddLog4Net();//需要配置文件
                                 //    })
      .UseServiceProviderFactory(new AutofacServiceProviderFactory())//设置工厂来替换实例
      .ConfigureWebHostDefaults(webBuilder =>
      {
          webBuilder.UseStartup<Startup>();//靠Startup来串起来MVC
      });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

Startup中加入如下代码

public void ConfigureContainer(ContainerBuilder containerBuilder)
 {
     //containerBuilder.RegisterType<TestServiceE>().As<ITestServiceE>().SingleInstance();
     containerBuilder.RegisterModule<CustomAutofacModule>();
 }
  • 1
  • 2
  • 3
  • 4
  • 5

对应于CustomAutofacModule类

protected override void Load(ContainerBuilder containerBuilder)
        {
            var assembly = this.GetType().GetTypeInfo().Assembly;
            var builder = new ContainerBuilder();
            var manager = new ApplicationPartManager();
            manager.ApplicationParts.Add(new AssemblyPart(assembly));
            manager.FeatureProviders.Add(new ControllerFeatureProvider());
            var feature = new ControllerFeature();
            manager.PopulateFeature(feature);
            builder.RegisterType<ApplicationPartManager>().AsSelf().SingleInstance();
            builder.RegisterTypes(feature.Controllers.Select(ti => ti.AsType()).ToArray()).PropertiesAutowired();
            //containerBuilder.RegisterType<FirstController>().PropertiesAutowired();

            //containerBuilder.Register(c => new CustomAutofacAop());//允许使用AOP,注册
            containerBuilder.RegisterType<TestServiceA>().As<ITestServiceA>().SingleInstance().PropertiesAutowired();
            containerBuilder.RegisterType<TestServiceC>().As<ITestServiceC>();
            containerBuilder.RegisterType<TestServiceB>().As<ITestServiceB>();
            containerBuilder.RegisterType<TestServiceD>().As<ITestServiceD>();
            containerBuilder.RegisterType<TestServiceE>().As<ITestServiceE>();

            // 允许当前注册的这个服务实例使用Aop
            //containerBuilder.RegisterType<A>().As<IA>();//.EnableInterfaceInterceptors();

            //containerBuilder.Register<FirstController>();

            //containerBuilder.RegisterType<JDDbContext>().As<DbContext>();
            //containerBuilder.RegisterType<CategoryService>().As<ICategoryService>();

            //containerBuilder.RegisterType<UserServiceTest>().As<IUserServiceTest>();
        }

    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

autofactAOP的实现首先引入:Autofac.Extras.DynamicProxy

public class CustomAutofacAop : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        Console.WriteLine($"invocation.Methond={invocation.Method}");
        Console.WriteLine($"invocation.Arguments={string.Join(",", invocation.Arguments)}");

        invocation.Proceed(); //继续执行

        Console.WriteLine($"方法{invocation.Method}执行完成了");
    }
}

public interface IA
{
    void Show(int id, string name);
}

[Intercept(typeof(CustomAutofacAop))]
public class A : IA
{
    public void Show(int id, string name)
    {
        Console.WriteLine($"This is {id} _ {name}");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

配置文件实现

public class CustomAutofacModule : Module
{
    protected override void Load(ContainerBuilder containerBuilder)
    {
        #region 依赖于配置文件配置服务 
        // 实例化
        IConfigurationBuilder config = new ConfigurationBuilder();
        //指定配置文件  这里的默认配置文件的路径在根目录下,课根据实际情况调整
        config.AddJsonFile("autofac.json");
        // Register the ConfigurationModule with Autofac. 
        IConfigurationRoot configBuild = config.Build();
        //读取配置文件里配置需要注册的服务
        var module = new ConfigurationModule(configBuild);
        containerBuilder.RegisterModule(module);
        #endregion
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

autofac.json 放在根目录如下:

{
    "defaultAssembly": "Microsoft.EntityFrameworkCore", // 抽象所在的程序集名称
    "components": [
      {
        "type": "Shop.EF.Model.shopdbContext,Shop.EF.Model", // 接口的实现类 全名称
        "services": [
          {
            "type": "Microsoft.EntityFrameworkCore.DbContext" // 接口的全名称
          }
        ],
        "instanceScope": "single-instance",
        "injectProperties": true
      },
      {
        "type": "Shop.Service.BaseService,Shop.Service", // 接口的实现类 全名称
        "services": [
          {
            "type": "Shop.Interface.IBaseService,Shop.Interface" // 接口的全名称
          }
        ],
        "instanceScope": "single-instance",
        "injectProperties": true
      },
      {
        "type": "Shop.Service.UserService,Shop.Service", // 接口的实现类 全名称
        "services": [
          {
            "type": "Shop.Interface.IUserService,Shop.Interface" // 接口的全名称
          }
        ],
        "instanceScope": "single-instance",
        "injectProperties": true
      },
      {
        "type": "Shop.Service.ProductService,Shop.Service", // 接口的实现类 全名称
        "services": [
          {
            "type": "Shop.Interface.IProductService,Shop.Interface" // 接口的全名称
          }
        ],
        "instanceScope": "single-instance",
        "injectProperties": true
      },
      {
        "type": "Shop.Service.OrderService,Shop.Service", // 接口的实现类 全名称
        "services": [
          {
            "type": "Shop.Interface.IOrderService,Shop.Interface" // 接口的全名称
          }
        ],
        "instanceScope": "single-instance",
        "injectProperties": true
      }
    ]
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

asp.net core3.1 实战开发(autofact的使用替换框架的IOC实现AOP)

原文:https://www.cnblogs.com/lonelyxmas/p/12879995.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!