ASP.net core Autofac泛型依赖注入

软件发布|下载排行|最新软件

当前位置:首页IT学院IT技术

ASP.net core Autofac泛型依赖注入

骗你学计算机   2022-06-03 我要评论

什么是泛型依赖注入

创建两个带泛型的类,并配置两者的依赖关系,对于继承这两个类的子类,如果泛型相同,则会继承这种依赖关系:

如上图:

定义了两个泛型base类:BaseService和BaseRepository

对于UserService和UserRpository分别继承两个base类,泛型都是User,则他们俩继承了父类的依赖关系。

.net core里实现泛型依赖注入

安装Autofac

先看项目结构

IMyRepository定义仓储接口

    public interface IMyRepository<T> where T: class
    {
        string GetTypeof();
    }

MyRepositoryBase仓储实现

    public class MyRepositoryBase<T> : IMyRepository<T> where T : class
    {
        public string GetTypeof()
        {
            return typeof(T).Name; //通过typeof可以知道泛型的名字
        }
    }

CustomAutofacModule 公共的依赖注入类

    public class CustomAutofacModule : Module
    {
        public CustomAutofacModule(ContainerBuilder builder) {
        }
        /// <summary>
        /// AutoFac注册类
        /// </summary>
        /// <param name="builder"></param>
        protected override void Load(ContainerBuilder builder)
        {
            builder.RegisterGeneric(typeof(MyRepositoryBase<>)).As(typeof(IMyRepository<>)).InstancePerDependency();//注册仓储泛型
//builder.RegisterGeneric(typeof(MyRepositoryBase<,>)).As(typeof(IMyRepository<,>)).InstancePerDependency();//注册仓储泛型 2个以上的泛型参数
         //  builder.RegisterType<myAssembly>().As<ImyAssembly>();   //普通依赖注入
        }
    }

在Program声明实现依赖注入

    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }
        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                //改用Autofac来实现依赖注入
                .UseServiceProviderFactory(new AutofacServiceProviderFactory())
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }

修改Startup

运行时候触发CustomAutofacModule

    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }
        public IConfiguration Configuration { get; }
        //autofac 新增
        public ILifetimeScope AutofacContainer { get; private set; }
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
        }
        public void ConfigureContainer(ContainerBuilder builder)
        {
            // 直接用Autofac注册我们自定义的 
            builder.RegisterModule(new CustomAutofacModule(builder));
        }
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            //autofac 新增 
            this.AutofacContainer = app.ApplicationServices.GetAutofacRoot();
            app.UseRouting();
            app.UseAuthorization();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }

在Home控制器中使用

    [ApiController]
    [Route("[controller]")]
    public class HomeController : ControllerBase
    {
        //public IMyRepository<User> _UserServer { get; set; }
        private readonly IMyRepository<User> _UserServer;
        private readonly IMyRepository<Role> _RoleServer;
        public HomeController(IMyRepository<User> UserServer, IMyRepository<Role> RoleServer)
        {
            _UserServer = UserServer;
            _RoleServer = RoleServer;
        }
        [Route("Get")]
        public string Get() {
            return _UserServer.GetTypeof();//"user"; //
        }
        [Route("GetRole")]
        public string GetRole()
        {
            return _RoleServer.GetTypeof();//"role"; //
        }
    }

可以看到 不同的地方实现不同的对象

番外:

我是因为看到ABP框架的IRepository的实现才研究泛型依赖注入的用法的。

ABP框架吧Autofac已经 封装为IocManager 了

所以ABP框架不需要 引入Autofac框架。只需要在对应的XXXCoreModule 中的Initialize()方法声明依赖注入便可

IocManager.Register(typeof(IMyRepository<>), typeof(MyRepositoryBase<>), DependencyLifeStyle.Transient);

如果是2个以上的泛型写法是

 IocManager.Register(typeof(IAmbientScopeProvider<,>), typeof(DataContextAmbientScopeProvider<,>), DependencyLifeStyle.Transient);

DependencyLifeStyle.Transient 的作用

Transient :瞬态,要么作用域是整个进程,要么作用域是一个请求,而这里的 Transient 就没有作用域概念了,注入一次 实例化一次 最明显的区别,属性注入是不可用的,只能构造函数注入

Singleton:可以在你的进程中保持着一个实例,也就是说仅有一次实例化 最明显的区别,属性注入是可用的

番外2:

看到了很多教程是不用声明CustomAutofacModule类的直接在Startup声明依赖注入就可以的。但是那是core 2.0的写法。core 3.0 下面的写法是会报错的

public static IContainer AutofacContainer;
// This method gets called by the runtime. Use this method to add services to the container.
public IServiceProvider ConfigureServices(IServiceCollection services)
{
    //注册服务进 IServiceCollection
    services.AddMvc();
    ContainerBuilder builder = new ContainerBuilder();
    //将services中的服务填充到Autofac中.
    builder.Populate(services);
    //新模块组件注册
    builder.RegisterModule<DefaultModuleRegister>();
    //创建容器.
    AutofacContainer = builder.Build();
    //使用容器创建 AutofacServiceProvider 
    return new AutofacServiceProvider(AutofacContainer);
}

Copyright 2022 版权所有 软件发布 访问手机版

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 联系我们