ASP.NET Core 3.1系列(25)——Autofac中的泛型注册和程序集注册

news2024/11/16 23:35:16

1、前言

在实际开发业务中,泛型的应用非常广泛,而这也就产生了一个问题:泛型类和泛型接口该怎么注册?难道要开发者一行一行去写泛型构造参数吗?同时,实际业务中往往也会对项目进行分层设计,例如接口层、实现层。对于这种处于不同程序集的接口和类,又有没有什么高效的方法对其进行处理呢?本文就来介绍一下如何利用Autofac来处理这两类问题。

2、Autofac中的泛型注册

新建泛型接口、泛型类、实体类,代码如下:

public interface IService<TEntity> where TEntity : class
{
    string Get();
}

public class Service<TEntity> : IService<TEntity> where TEntity : class
{
    public string Get()
    {
        return typeof(TEntity).FullName;
    }
}

public class Cat { }
public class Dog { }

如果使用Autofac中的基础注册方法,代码如下:

using Autofac;
using System;

namespace App
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // 注册接口和类
            ContainerBuilder builder = new ContainerBuilder();
            builder.RegisterType<Service<Cat>>().As<IService<Cat>>();
            builder.RegisterType<Service<Dog>>().As<IService<Dog>>();

            // 构建容器
            IContainer container = builder.Build();

            // Cat
            IService<Cat> cat = container.Resolve<IService<Cat>>();
            Console.WriteLine(cat.Get());

            // Dog
            IService<Dog> dog = container.Resolve<IService<Dog>>();
            Console.WriteLine(dog.Get());
        }
    }
}

运行结果如下所示:

App.Cat
App.Dog

上面的代码虽然实现了泛型注册,但问题也是显而易见的:一旦实体类数量较多,开发者需要手写大量注册代码。在Autofac中,我们可以使用RegisterGeneric方法来实现泛型注册,代码如下:

using Autofac;
using System;

namespace App
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // 注册接口和类
            ContainerBuilder builder = new ContainerBuilder();
            builder.RegisterGeneric(typeof(Service<>)).As(typeof(IService<>));

            // 构建容器
            IContainer container = builder.Build();

            // Cat
            IService<Cat> cat = container.Resolve<IService<Cat>>();
            Console.WriteLine(cat.Get());

            // Dog
            IService<Dog> dog = container.Resolve<IService<Dog>>();
            Console.WriteLine(dog.Get());
        }
    }
}

使用RegisterGeneric方法的好处就是无需写大量的带泛型构造参数的注册代码。运行结果如下所示:

App.Cat
App.Dog

3、Autofac中的程序集注册

在实际业务中,一般会对项目进行分层设计。下图显示了一个简易的分层项目:

在这里插入图片描述

Repository层代码如下所示:

namespace App.Repository.Contract
{
    public interface ICatRepository
    {
        string GetCatMsg();
    }
}
namespace App.Repository.Contract
{
    public interface IDogRepository
    {
        string GetDogMsg();
    }
}
using App.Repository.Contract;

namespace App.Repository
{
    public class CatRepository : ICatRepository
    {
        public string GetCatMsg()
        {
            return "This is cat";
        }
    }
}
using App.Repository.Contract;

namespace App.Repository
{
    public class DogRepository : IDogRepository
    {
        public string GetDogMsg()
        {
            return "This is dog";
        }
    }
}

Service层代码如下所示:

namespace App.Service.Contract
{
    public interface ICatService
    {
        string Get();
    }
}
namespace App.Service.Contract
{
    public interface IDogService
    {
        string Get();
    }
}
using App.Repository.Contract;
using App.Service.Contract;

namespace App.Service
{
    public class CatService : ICatService
    {
        protected readonly ICatRepository _repository;

        public CatService(ICatRepository repository)
        {
            _repository = repository;
        }

        public string Get()
        {
            return _repository.GetCatMsg();
        }
    }
}
using App.Repository.Contract;
using App.Service.Contract;

namespace App.Service
{
    public class DogService : IDogService
    {
        protected readonly IDogRepository _repository;

        public DogService(IDogRepository repository)
        {
            _repository = repository;
        }

        public string Get()
        {
            return _repository.GetDogMsg();
        }
    }
}

如果使用Autofac的基础注册方法,可以写成如下形式:

using App.Repository;
using App.Repository.Contract;
using App.Service;
using App.Service.Contract;
using Autofac;
using System;

namespace App
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // 注册接口和类
            ContainerBuilder builder = new ContainerBuilder();
            builder.RegisterType<CatRepository>().As<ICatRepository>();
            builder.RegisterType<DogRepository>().As<IDogRepository>();
            builder.RegisterType<CatService>().As<ICatService>();
            builder.RegisterType<DogService>().As<IDogService>();

            // 构建容器
            IContainer container = builder.Build();

            // ICatService
            ICatService cat = container.Resolve<ICatService>();
            Console.WriteLine(cat.Get());

            // IDogService
            IDogService dog = container.Resolve<IDogService>();
            Console.WriteLine(dog.Get());
        }
    }
}

运行结果如下所示:

This is cat
This is dog

上面的代码虽然能够实现注册,但其实问题跟泛型注册一样:如果有很多接口和类,那么就需要写大量重复代码。一般来说,分层项目会对各层中的文件命名做一定的限制。例如,仓储层中的文件必须以Repository结尾,服务层中的文件必须以Service结尾。这就给我们提供了一个思路:能否通过加载程序集批量获取文件名称,通过文件名称的匹配来实现接口和类的注册?其实,Autofac中的RegisterAssemblyTypes方法就支持这么做,代码如下:

using App.Service.Contract;
using Autofac;
using System;
using System.Reflection;

namespace App
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // 注册接口和类
            ContainerBuilder builder = new ContainerBuilder();

            // 注册Repository
            Assembly repository = Assembly.Load("App.Repository");
            Assembly repositoryContract = Assembly.Load("App.Repository.Contract");
            builder.RegisterAssemblyTypes(repository, repositoryContract)
                   .Where(p => p.Name.EndsWith("Repository"))
                   .AsImplementedInterfaces();

            // 注册Service
            Assembly service = Assembly.Load("App.Service");
            Assembly serviceContract = Assembly.Load("App.Service.Contract");
            builder.RegisterAssemblyTypes(service, serviceContract)
                   .Where(p => p.Name.EndsWith("Service"))
                   .AsImplementedInterfaces();

            // 构建容器
            IContainer container = builder.Build();

            // ICatService
            ICatService cat = container.Resolve<ICatService>();
            Console.WriteLine(cat.Get());

            // IDogService
            IDogService dog = container.Resolve<IDogService>();
            Console.WriteLine(dog.Get());
        }
    }
}

运行结果如下所示:

This is cat
This is dog

程序集注册的好处是显而易见的:如果后续需要添加新的接口和类,我们也不需要修改代码,因为Autofac会自动扫描类库中文件,然后通过名称匹配进行注册。

4、结语

本文主要介绍了Autofac中的泛型注册和程序集注册,这两种注册方法具有非常高的实用性。如果你对项目进行了分层设计,同时项目中也存在大量泛型接口和泛型类,那么使用泛型注册和程序集注册将会达到事半功倍的效果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/160599.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【十】Netty WebSocket协议栈开发

Netty WebSocket协议栈开发背景介绍HTTP 协议的弊端WebSocket 介绍WebSocket 特点WebSocket 连接建立Socket生命周期WebSocket关闭开发WebSocket 服务端功能介绍流程图代码实现jar 依赖WebSocket 服务端启动类 WebSocketServer服务端业务处理类 WebSocketServerHandlerWebSocke…

nacos的部署以及nacos启动报错“Unable to start embedded Tomcat”(部分解决)

这几天有一个基于yshop改编的SpringBoot的项目开发需求&#xff0c;本地需要下载使用nacos-server进行部署和开发&#xff0c;于是下载了nacos-server-2.0.3,并将其解压在一个没有中文路径的地方。 接下来根据nacos需求&#xff0c;设置了JAVA_HOME的环境变量&#xff1a; 修…

防火墙NAT综合实验

实验要求 1.内网网段配置动态pat将内网192.168.1.0网段映射到防火墙外网接口上 2.dmz区域服务器做静态pat将两台服务器对应到一个外网接口的不同端口 3.开启nat 控制 4.对内网网段192.168.2.0或豁免能够发访问外网 5.并通过远程进行验证 实验命令 ciscoasa# conf t cisco…

如何快速做好SEO优化?怎样综合查询seo?

本篇接着讲新手优化网站的技巧及应该注意什么方面&#xff0c;一起来看看吧&#xff01; 6.优化你的图片 从可读性的角度来看&#xff0c;图像非常重要。他们帮助可视化你的内容&#xff0c;帮助读者更容易理解。但它们对SEO也很重要&#xff0c;因为它们可以帮助你的网站被抓…

MySQL——SQL逻辑语句相同但是性能相差巨大?

在 MySQL 中&#xff0c;有很多看上去逻辑相同&#xff0c;但性能却差异巨大的 SQL 语句。对这些语句使用不当的话&#xff0c;就会不经意间导致整个数据库的压力变大。 下面通过三个案例对SQL语句进行分析&#xff1a; 案例一&#xff1a;条件字段函数操作 假设你现在维护了…

51单片机特性概览

51单片机指的是使用英特尔8051指令集的微控制器。 首先要了解什么是微控制器。 一、什么是微控制器&#xff1f; 微控制器包括&#xff1a; CPU其他组件(可能包括RAM,ROM,I/O端口&#xff0c;定时器、计数器、通信端口)&#xff0c; 而微处理器只包含CPU。 一开始只有微处…

适应性学习率

目录 适应性学习率 Adaptive learning rate 为什么不是临界点仍会导致训练停止 示例一示例二 RMSRMSPropAdam学习率还和时间有关 Learin Rate DecayWarm up 2021 - 类神经网络训练不起来怎么办(三) 自动调整学习率 (Learning Rate)适应性学习率 Adaptive learning rate 一般…

团队协作软件如何整合内容营销

每个内容营销团队都以不同的方式管理他们的流程和工作流程——无论是为成长中的团队扩展编辑流程&#xff0c;还是视频和社交媒体活动规划。优化内容营销项目管理就是降低复杂性和更有效地管理工作。 但是&#xff0c;为什么正确地做到这一点如此重要呢&#xff1f;与对外营…

第一个uni-app程序小结

工院喵开发小结 这是一篇关于uniapp新手写微信小程序的收获和踩坑总结。 目录工院喵开发小结一、架构二、收获1. 一些扩展组件的使用a. uni-uib. uni-listc. 栅格系统d. uni.scss辅助样式e. uni-easyinput 增强输入框f. uni-fab悬浮按钮g. swiper2. api管理3. 页面跳转传参4. …

iOS 语言基础初探 Xcode 工具

前言&#xff1a; 作为 iOS 开发的主要应用工具之一&#xff0c;Xcode 已经越来越被业内认可&#xff0c;本章节将针对此官方开发工具&#xff0c;为同学解读 Xcode 的基本情况&#xff0c;认识 Xcode 的工程体系&#xff0c;带领大家进入 iOS 开发第一步。 &#x1f3b6;文章目…

SAP入门技术分享四:模块化程序

模块化程序1.子程序概要2.子程序定义3.子程序参数&#xff08;1&#xff09;传递参数的方法&#xff08;2&#xff09;定义参数类型&#xff08;3&#xff09;参数与结构体&#xff08;4&#xff09;参数与内表4.调用子程序&#xff08;1&#xff09;调用程序内部子程序&#x…

vue npm link关联本地组件库

什么是 npm link 就是把你在本地开发好的文件做一个映射和链接&#xff0c;当你在 本地开发一个a项目&#xff0c;你的本地b项目想使用a项目下的组件 这时候就是需要进行npm link链接起来 a项目的运行效果 b项目的运行效果&#xff1a; 想要实现的效果&#xff1a;(在b项目上…

Oracle SQL Developer使用dbms_output.put_line显示输出

dbms输出 点击DBMS输出左侧的号&#xff0c;选择需要输出的数据库&#xff0c;点击确定 与步骤2选择相同数据库&#xff0c;右击数据库&#xff0c;选择打开SQL工作表(T) 在工作表中执行语句 declare --定义&#xff0c;相当于声明属性。t_a varchar2(20);--声明自定义属…

怎么写一篇计算机SCI论文初稿? - 易智编译EaseEditing

一、SCI论文的要求 SCI论文的核心是创新性。对于这个方面来说主要就是针对于论文的观点正确&#xff0c;文字通畅&#xff0c;逻辑严密&#xff0c;结构合理&#xff0c;结论有创新等等。 二、SCI论文格式规范 每一个SCI期刊都有自己特定的宗旨、栏目和专业定位&#xff0c;投…

TCP通信机制:三次握手、四次挥手、滑动窗口

欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起探讨和分享Linux C/C/Python/Shell编程、机器人技术、机器学习、机器视觉、嵌入式AI相关领域的知识和技术。 TCP通信机制1. TCP三次握手2. TCP四次挥手3. TCP连接与数据传输过程4. TCP滑动窗口机制5. server服务端…

这套设备管理方案助你效率10倍提升

车间工厂等货物人员密集场所&#xff0c;对消防安全的要求很高。消防设备管理自然是生产制造型企业的核心之一。消防设施的有效管理&#xff0c;既要保证日常巡检工作的有效性&#xff0c;又要在设备出现故障后及时响应。在此基础上还要对整体管理情况进行数据分析&#xff0c;…

振弦采集模块的各种参数操作

振弦采集模块的各种参数操作 固件版本读取 点击指令区【 读取版本】 按钮&#xff0c;读取当前连接模块的固件版本信息&#xff0c;读取到的版本信息显示于按钮右侧。 VMTool 会根据读取到的版本不同对功能和界面做出调整&#xff0c;故此&#xff0c; 在使用 VMTool 时&#…

Workfine新手入门:给图片加水印

哈喽&#xff0c;我是办公助手小W&#xff0c;又到了跟大家分享办公小技巧的时候啦&#xff01; 最近Workfine5.0最新版本上线后&#xff0c;一直有人问到底有啥新功能啊&#xff1f;与往期版本有何不同呢&#xff1f;小W亲自去体验了一番&#xff0c;最大的一个亮点就是新增了…

90、【树与二叉树】leetcode ——104. 二叉树的最大深度:层次遍历+DFS+子问题分解(C++版本)

解题思路 原题链接&#xff1a;104. 二叉树的最大深度 解题思路 1、迭代法&#xff1a;层次遍历BFS /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), rig…

Blender 物理属性 (二)布料和碰撞

文章目录添加与去除布料查看布料效果布料的预设属性(模拟不同的布料效果)布料与其他物体碰撞布料的自交叉问题布料钉固制作一个窗帘添加与去除布料 1 添加&#xff1a;物体模式选中一个物体&#xff0c;属性栏/物理属性&#xff08;蓝色圆圈&#xff09;&#xff0c;选择布料 …