什么是工厂模式

工厂模式是最常用的设计模式之一,属于创建型模式。

有点:

  • 解耦,可以把对象的创建和过程分开
  • 减少代码量,易于维护

什么时候用?

当一个抽象类有多个实现的时候,需要多次实例化的时候,就要考虑使用工厂模式。

比如:登录的抽象类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容器中获取注入的实例,所以之前的MobileCodeLoginUserNameAndPasswordLogin需要注入到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 中使用工厂模式的更多相关文章

  1. (13)ASP.NET Core 中的选项模式(Options)

    1.前言 选项(Options)模式是对配置(Configuration)的功能的延伸.在12章(ASP.NET Core中的配置二)Configuration中有介绍过该功能(绑定到实体类.绑定至对 ...

  2. PHP中“简单工厂模式”实例讲解

    原创文章,转载请注明出处:http://www.cnblogs.com/hongfei/archive/2012/07/07/2580776.html 简单工厂模式:①抽象基类:类中定义抽象一些方法, ...

  3. JS中的工厂模式

    .一个栗子: var BicycleShop = function(){}; BicycleShop.prototype = { sellBicycle : function( model ){ va ...

  4. Spring中的工厂模式和单例模式

    Spring预备知识(适合中小型项目) 作用:集成和管理其他框架 工厂模式: A  a  = new A( ); 将类所要创建的对象写入工厂,统一进行管理 package com.spring; pu ...

  5. 【QtAV】QtAV中的工厂模式

    QtAV中的各个模块大量使用的工厂模式,下面对其实现进行介绍. 工厂模式的使用 以 VideoRenderer 类为例子,他含有下面3个工厂模式相关的方法,Register方法用于给一个产品<c ...

  6. spring中的工厂模式

    spring的bean的创建原理就是框架利用反射创建出实例对象 工厂模式:工厂帮我们创建对象:有一个专门帮我们创建对象的类,我们把这个类叫做工厂类. 例如:Plane plane = PlaneFac ...

  7. PHP中“简单工厂模式”实例讲解(转)

      ? 1 2 3 4 5 6 7 8 原创文章,转载请注明出处:http://www.cnblogs.com/hongfei/archive/2012/07/07/2580776.html   简单 ...

  8. c#中简单工厂模式

    运算类 public class yunsuan { public static operation create(string operate) { operation oper = null; s ...

  9. 【原创】EntityFramework Core 中使用 CodeFirst 模式时 PowerShell 版本问题及解决

    一.描述: 在使用 Entity Framework Core 时,使用 CodeFirst 模式, 在 VS 中的 PMC(nuget 包管理 控制台) 控制台界面使用如下命令: Install-P ...

随机推荐

  1. 【面试普通人VS高手系列】innoDB如何解决幻读

    前天有个去快手面试的小伙伴私信我,他遇到了这样一个问题: "InnoDB如何解决幻读"? 这个问题确实不是很好回答,在实际应用中,很多同学几乎都不关注数据库的事务隔离性. 所有问题 ...

  2. es6 class解析

    直入主题.源代码如下: class A{ aName = 'A' constructor(aAge){ this.aAge = aAge } static aStatic = 'aStatic' } ...

  3. 解析数仓OLAP函数:ROLLUP、CUBE、GROUPING SETS

    摘要:GaussDB(DWS) ROLLUP,CUBE,GROUPING SETS等OLAP函数的原理解析. 本文分享自华为云社区<GaussDB(DWS) OLAP函数浅析>,作者: D ...

  4. 【ACM程序设计】求最小生成树 Kuskual算法

    Kuskual算法 流程 1 将图G看做一个森林,每个顶点为一棵独立的树 2 将所有的边加入集合S,即一开始S = E( 并查集) 3 从S中拿出一条最短的边(u,v),如果(u,v)不在同一棵树内, ...

  5. DNS软件bind-实现DNS服务器

    DNS服务器软件::bind,powerdns,dnsmasq,unbound,coredns BIND相关程序包 bind:服务器 bind-libs:相关库 bind-utils:客户端 bind ...

  6. 图文详解:小白也能看懂的 Kubernetes

    Kubernetes 这个单词来自于希腊语,含义是舵手或领航员 .其词根是 governor 和 cybernetic.K8s 是它的缩写,用 8 字替代了"ubernete". ...

  7. 个人&博客信息

                博客配置 服务器:无 配置链接:在博客园中安装皮肤 皮肤:GEEK by GUANGZAN           个人简介 本蒟蒻是广东中山人 如果您有一些问题,请发送邮件至mo ...

  8. 生成器对象(自定义迭代器),自定义range方法,模块

    自定义迭代器 一 .生成器与yield ''' 我们得到一个迭代器通常都是调用可迭代对象的__iter__方法 ,例如 list.iter() 得到一个迭代器, 但是当list很大时候,就违背了pyt ...

  9. MySQL 的 EXPLAIN 语句及用法

    在MySQL中 DESCRIBE 和 EXPLAIN 语句是相同的意思.DESCRIBE 语句多用于获取表结构,而 EXPLAIN 语句用于获取查询执行计划(用于解释MySQL如何执行查询语句). 通 ...

  10. e2fsck-磁盘分区修复

    检查 ext2/ext3/ext4 类型文件系统. 语法 e2fsck [-panyrcdfvtDFV] [-b superblock] [-B blocksize] [-I inode_buffer ...