ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

DDD 引入Autofac对各层进行解耦,并编写通用的方法拦截器,工作单元,仓储实现

2022-02-05 19:34:10  阅读:238  来源: 互联网

标签:Autofac 拦截器 builder Framework invocation using public DDD


从零开始写一个领域模型的框架

每篇文章都会打一个对应的 tag

Github 仓库地址

 

这版代码

  使用 Autofac 代替 .NET Core内置的依赖注入框架

  使用 Autofac 定义方法拦截器,对指定的方法进行拦截操作

  工作单元 (目前只写了根据id 获取一条数据的功能)

 

使用 Autofac 的两个原因

  一、灵活的调用某个类型的任意一个构造方法,创建对象

  二、自定义方法拦截器

 

获取Autofac的IoC容器,ORM对象转领域对象

Startup.ConfigureContainer

// 获取到 Autofac 的容器
builder.RegisterBuildCallback(scope =>
{
    AppSettings.AppAutofacContainer((IContainer)scope);
});

 

public virtual IDomain Find(Guid keyId, bool readOnly = false)
{
    OrmEntity entity = UnitOfWork.CreateSet<OrmEntity>().Find(keyId);
   // Autofac 获取到容器之后,可以直接通过指定的参数调用相应的构造函数重载,创建实例
    IDomain domain = AppSettings.AutofacContainer.Resolve<IDomain>(new NamedParameter("entity", entity));

    return domain;
}

 

Autofac 自定义方法拦截器

AutofacAOP.cs  拦截器

using Castle.DynamicProxy;
using System;
using System.Linq;

namespace Core2022.Framework.UnitOfWork
{
    public class AutofacAOP : IInterceptor
    {
        public void Intercept(IInvocation invocation)
        {
            DateTime startTime = DateTime.Now;
            //objs 是当前拦截方法的入参
            object[] objs = invocation.Arguments;
            invocation.Proceed();
            // ret 是当前方法的返回值
            object ret = invocation.ReturnValue;
            DateTime endTime = DateTime.Now;

            if (invocation.Method.CustomAttributes?.FirstOrDefault(i => i.AttributeType.Name == "AOPLogAttribute") != null)
            {
                if (invocation.Method.Name == "Find") // 方法名字
                {
                  // 自定义逻辑
                }
            }
        }
    }
}

 

AutofacInjectionServicesExtension.cs 注册拦截器

using Autofac;
using Autofac.Extras.DynamicProxy;
using Core2022.Framework.Settings;
using Core2022.Framework.UnitOfWork;
using System;
using System.Collections.Generic;
using System.Reflection;

namespace Core2022.Framework.Commons.Autofac
{
    public static class AutofacInjectionServicesExtension
    {

        public static ContainerBuilder AutofacInjectionServices(this ContainerBuilder builder)
        {
            foreach (var assemblyString in AppSettings.InjectionServices.AssemblyStrings)
            {
                builder.RegisterType<AutofacAOP>();
                var assembly = Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory + assemblyString);
                builder.RegisterAssemblyTypes(assembly)
                    .AsImplementedInterfaces()
                    .InstancePerDependency()
                    .PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies)
                    .EnableClassInterceptors()
                    .InterceptedBy(new List<Type>().ToArray());
            }

            return builder;
        }
    }
}

AutofacAOP 用来拦截指定方法的拦截器

把 AutofacAOP 注册到 Autofac IoC容器中

  builder.RegisterType<AutofacAOP>();

  .EnableClassInterceptors()

  .InterceptedBy(new List<Type>().ToArray());

对指定的方法进行拦截设置

  [Intercept(typeof(AutofacAOP))]

  public abstract class BaseRepository<IDomain, OrmEntity> : IBaseRepository<IDomain, OrmEntity>

  [AOPLog]

  public virtual IDomain Find(Guid keyId, bool readOnly = false)

使用

  在 AutofacAOP 中的 Intercept 方法中根据参数进行自定义操作

  invocation.Method 当前方法的信息

  invocation.Arguments 方法执行前,传入的参数

  invocation.ReturnValue 方法执行后,返回的参数

 

Autofac 依赖注入

Startup.ConfigureContainer

/// <summary>
/// Autofac 依赖注入
/// </summary>
/// <param name="builder"></param>
public void ConfigureContainer(ContainerBuilder builder)
{
    // Autofac 注入Orm对象
    builder.AutofacInjectionOrmModel();
    // Autofac 注入各层之间的依赖
    builder.AutofacInjectionServices();
    builder.RegisterBuildCallback(scope =>
    {
        AppSettings.AppAutofacContainer((IContainer)scope);
    });
}

 

using Autofac;
using Core2022.Framework.Settings;
using System;
using System.Reflection;

namespace Core2022.Framework.Commons.Autofac
{
    public static class AutofacInjectionOrmModelExtension
    {
        public static ContainerBuilder AutofacInjectionOrmModel(this ContainerBuilder builder)
        {
            foreach (var assemblyString in AppSettings.InjectionServices.AssemblyStrings)
            {
                var assembly = Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory + assemblyString);
            }

            return builder;
        }
    }
}

 

工作单元UnitOfWork

AppUnitOfWork.cs

using Core2022.Framework.Settings;
using Microsoft.EntityFrameworkCore;

namespace Core2022.Framework.UnitOfWork
{
    public class AppUnitOfWork : DbContext, IUnitOfWork
    {
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {

            optionsBuilder.UseSqlServer(AppSettings.ConnectionString);
            base.OnConfiguring(optionsBuilder);
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            AppSettings.OrmModelInit.ForEach(t =>
            {
                modelBuilder.Model.AddEntityType(t);
            });
            base.OnModelCreating(modelBuilder);
        }


        public DbSet<OrmEntity> CreateSet<OrmEntity>()
          where OrmEntity : class
        {
            return base.Set<OrmEntity>();
        }

    }
}

 

标签:Autofac,拦截器,builder,Framework,invocation,using,public,DDD
来源: https://www.cnblogs.com/ansheng/p/15864620.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有