什么是工厂模式

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

有点:

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

什么时候用?

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

比如:登录的抽象类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. 两数之和II_LeetCode_167_1099

    LeetCode_167原题链接:https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/ LeetCode_1099原题链 ...

  2. jni有关知识点总结

    一.c/c++语言: 1.关于动态链接库的搜索问题: LIBRARY_PATH is used by gcc before compilation to search for directories ...

  3. C++怎么实现多态?

    C++通过函数重载或模板实现编译期多态(静态绑定),通过虚函数实现运行时多态(动态绑定). 1.函数重载 #include <stdio.h> int add(int a, int b) ...

  4. clickhouse智能提示编辑器

    对于经常写sql的人来说智能提示是非常重要的,这个非常影响写sql的效率和心情. 这里说的智能提示不仅仅是关键字(select等)的智能提示,还得要做到表字段的智能提示. 例如: 下面是mysql的智 ...

  5. 详解javascript的eventloop(二):eventloop和dom渲染

    记住: JS是单线程的,他和dom渲染共用一个线程 JS执行的时候,会给dom渲染留一些时机 上一篇讲到eventloop的执行机制,但是在这个机制中的call stack执行完成后(包括第一遍的ev ...

  6. jmeter并发设置的原理

    目录 简介 广义并发 绝对并发 简介 ​ 性能测试过程中是否需要进行同步定时器的设置,需要根据实际情况来考虑. ​ 举个栗子来讲是我们的双十一秒杀活动,这时候就必须实现请求数量达到一定数量后同时向服务 ...

  7. 『忘了再学』Shell基础 — 12、用户自定义变量

    目录 1.变量定义 2.变量调用 3.变量的修改 4.查看变量 (1)-u选项说明: (2)-x选项说明: (3)set命令说明: 5.变量删除 1.变量定义 变量正确定义. 格式:变量名=" ...

  8. Git批量下载MODIS数据

    1.download.sh获取 EarthData(需注册账号)中获取MODIS的产品类型.地理范围.时间年份等,进入下载页面Download Status 下载点击得到_download.sh 文件 ...

  9. PowerJob高级特效-容器部署完整教程

    介绍 powerjob提供了容器功能,用来做一些灵活的任务处理.这里容器为 JVM 级容器,而不是操作系统级容器(Docker).(至于为什么取"容器"这个有歧义的名字是因为作者没 ...

  10. spring boot 集成 rabbitmq 指南

    先决条件 rabbitmq server 安装参考 一个添加了 web 依赖的 spring boot 项目 我的版本是 2.5.2 添加 maven 依赖 <dependency> &l ...