.Net Core 中使用工厂模式
什么是工厂模式
工厂模式是最常用的设计模式之一,属于创建型模式。
有点:
- 解耦,可以把对象的创建和过程分开
- 减少代码量,易于维护
什么时候用?
当一个抽象类有多个实现的时候,需要多次实例化的时候,就要考虑使用工厂模式。
比如:登录的抽象类ILoginBusiness,它有2个实现,一个用用户名密码登录,一个用手机号验证码登录
public interface ILoginBusiness
{
Task Login(LoginInputDTO input);
}
public class MobileCodeLogin : ILoginBusiness
{
public Task Login(LoginInputDTO input)
{
// todo
}
}
public class UserNameAndPasswordLogin : ILoginBusiness
{
public Task Login(LoginInputDTO input)
{
// todo
}
}
按照原有方式,我们会根据某个条件去实例化,比如loginType
ILoginBusiness loginBusiness;
if (loginType == 1)
{
loginBusiness = new MobileCodeLogin();
}
else
{
loginBusiness = new UserNameAndPasswordLogin()
}
当有多种实例的话,就需要更多的ifelse或者switch,工厂模式的作用就是把这种建造对象的方法放在工厂类去解决,统一管理统一维护。
实现方式
public interface ILoginFactory
{
ILoginBusiness Create(LoginInputDTO inputDto);
}
public class LoginFactory : BaseBusiness, ILoginFactory, ITransientDependency
{
public ILoginBusiness Create(LoginInputDTO inputDto)
{
return inputDto.LoginType == LoginType.UserNameAndPwd
? AppDependencyResolver.Current.GetService<UserNameAndPwdLogin>()
: (ILoginBusiness)AppDependencyResolver.Current.GetService<MobileCodeLogin>();
}
public LoginFactory(IRepository repository) : base(repository)
{
}
}
如果用new的方法去实例化,就需要把构造方法中的参数在工厂的构造方法里也加入进去,所以这里用了一个AppDependencyResolver,这里的AppDependencyResolver.Current.GetService<T>是从当前IOC容器中获取注入的实例,所以之前的MobileCodeLogin和UserNameAndPasswordLogin需要注入到IOC实例中,在我们项目就是继承ITransientDependency
public class AppDependencyResolver
{
private static AppDependencyResolver _resolver;
public static AppDependencyResolver Current
{
get
{
if (_resolver == null)
throw new Exception("AppDependencyResolver not initialized");
return _resolver;
}
}
// 在startUp的ConfigureService的最后,加入AppDependencyResolver.Init(services.BuildServiceProvider());
public static void Init(IServiceProvider service)
{
_resolver = new AppDependencyResolver(service);
}
private AppDependencyResolver(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
private readonly IServiceProvider _serviceProvider;
public object GetService(Type serviceType)
{
return _serviceProvider.GetService(serviceType);
}
public T GetService<T>()
{
return _serviceProvider.GetService<T>();
}
}
关于工厂的单元测
关于工厂,我们只需要测返回的对象是否是我们需要的就可以了,至于对象的执行对不对不需要关心
[Theory(DisplayName = "测试登录工厂")]
[InlineData(LoginType.MobileCode, typeof(MobileCodeLogin))]
[InlineData(LoginType.UserNameAndPwd, typeof(UserNameAndPwdLogin))]
public void CreateTests(LoginType loginType, Type expectedType)
{
Mock<IRepository> mock = new Mock<IRepository>();
ILoginFactory factory = new LoginFactory(mock.Object);
var login = factory.Create(new LoginInputDTO()
{
LoginType = loginType
});
Assert.IsType(expectedType, login);
}
.Net Core 中使用工厂模式的更多相关文章
- (13)ASP.NET Core 中的选项模式(Options)
1.前言 选项(Options)模式是对配置(Configuration)的功能的延伸.在12章(ASP.NET Core中的配置二)Configuration中有介绍过该功能(绑定到实体类.绑定至对 ...
- PHP中“简单工厂模式”实例讲解
原创文章,转载请注明出处:http://www.cnblogs.com/hongfei/archive/2012/07/07/2580776.html 简单工厂模式:①抽象基类:类中定义抽象一些方法, ...
- JS中的工厂模式
.一个栗子: var BicycleShop = function(){}; BicycleShop.prototype = { sellBicycle : function( model ){ va ...
- Spring中的工厂模式和单例模式
Spring预备知识(适合中小型项目) 作用:集成和管理其他框架 工厂模式: A a = new A( ); 将类所要创建的对象写入工厂,统一进行管理 package com.spring; pu ...
- 【QtAV】QtAV中的工厂模式
QtAV中的各个模块大量使用的工厂模式,下面对其实现进行介绍. 工厂模式的使用 以 VideoRenderer 类为例子,他含有下面3个工厂模式相关的方法,Register方法用于给一个产品<c ...
- spring中的工厂模式
spring的bean的创建原理就是框架利用反射创建出实例对象 工厂模式:工厂帮我们创建对象:有一个专门帮我们创建对象的类,我们把这个类叫做工厂类. 例如:Plane plane = PlaneFac ...
- PHP中“简单工厂模式”实例讲解(转)
? 1 2 3 4 5 6 7 8 原创文章,转载请注明出处:http://www.cnblogs.com/hongfei/archive/2012/07/07/2580776.html 简单 ...
- c#中简单工厂模式
运算类 public class yunsuan { public static operation create(string operate) { operation oper = null; s ...
- 【原创】EntityFramework Core 中使用 CodeFirst 模式时 PowerShell 版本问题及解决
一.描述: 在使用 Entity Framework Core 时,使用 CodeFirst 模式, 在 VS 中的 PMC(nuget 包管理 控制台) 控制台界面使用如下命令: Install-P ...
随机推荐
- 五、JDK的安装与配置
一.JDK下载与安装 1.1.下载JDK安装包 博主在这里给大家准备了一个64位操作系统的jdk1.8以便大家下载(使用的是迅雷) 点击此处下载 提取码:dfbt 如果其他小伙伴的电脑版本不一样,博主 ...
- Java语言学习day37--8月12日
今日内容介绍1.List接口2.Set接口3.判断集合唯一性原理 ###01List接口的特点 A:List接口的特点: a:它是一个元素存取有序的集合. 例如,存元素的顺序是11.22.33.那么 ...
- 论文解读(SelfGNN)《Self-supervised Graph Neural Networks without explicit negative sampling》
论文信息 论文标题:Self-supervised Graph Neural Networks without explicit negative sampling论文作者:Zekarias T. K ...
- Rust如何开发eBPF应用(一)?
前言 eBPF是一项革命性的技术,可以在Linux内核中运行沙盒程序,而无需重新编译内核或加载内核模块.它能够在许多内核 hook 点安全地执行字节码,主要应用在云原生网络.安全.跟踪监控等方面. e ...
- 使用 Prometheus Alertmanager 模块发送 Doris 异常信息至钉钉报警群
基础环境 1.Prometheus 版本:2.22.2 下载地址: https://github.com/prometheus/prometheus/releases/download/v2.22.2 ...
- 关于openstreet map的osm文件转shp文件方法(附arcgis10.2插件)
一.下载并安装对应arcgis版本的osm插件 对应arcgis版本的osm转换插件在arcgis官网可以下载 http://www.arcgis.com/home/search.html?q=Arc ...
- 雪花算法生成分布式ID
分布式主键ID生成方案 分布式主键ID的生成方案有以下几种: 数据库自增主键 缺点: 导入旧数据时,可能会ID重复,导致导入失败 分布式架构,多个Mysql实例可能会导致ID重复 UUID 缺点: 占 ...
- MySQL left join 引发的惨案
当我用这个进行更改值时,type未控制order表 其他数据被更改 还好备份数据表了(这里就体现了备份的重要性) UPDATE expense_order as a left join ( SELEC ...
- XCTF练习题---MISC---wireshark1
XCTF练习题---MISC---wireshark1 flag:flag{ffb7567a1d4f4abdffdb54e022f8facd} 解题步骤: 1.观察题目,下载附件 2.得到一个wire ...
- Neo4j数据和Cypher查询语法笔记
Cypher数据结构 Cypher的数据结构: 属性类型, 复合类型和结构类型 属性类型 属性类型 Integer Float String: 'Hello', "World" B ...