前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >.Net Core 中使用工厂模式

.Net Core 中使用工厂模式

作者头像
脑洞的蜂蜜
发布2022-06-27 14:31:32
3710
发布2022-06-27 14:31:32
举报
文章被收录于专栏:NetCoreNetCore

什么是工厂模式

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

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

什么时候用?

当一个抽象类有多个实现的时候,需要多次实例化的时候,就要考虑使用工厂模式。 比如:登录的抽象类ILoginBusiness,它有2个实现,一个用用户名密码登录,一个用手机号验证码登录

代码语言:javascript
复制
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

代码语言:javascript
复制
ILoginBusiness loginBusiness;
if (loginType == 1)
{
    loginBusiness = new MobileCodeLogin();
}
else
{
    loginBusiness = new UserNameAndPasswordLogin()
}

当有多种实例的话,就需要更多的ifelse或者switch,工厂模式的作用就是把这种建造对象的方法放在工厂类去解决,统一管理统一维护。

实现方式

代码语言:javascript
复制
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

代码语言:javascript
复制
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>();
    }
}

关于工厂的单元测

关于工厂,我们只需要测返回的对象是否是我们需要的就可以了,至于对象的执行对不对不需要关心

代码语言:javascript
复制
[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);
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-06-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是工厂模式
  • 什么时候用?
  • 实现方式
  • 关于工厂的单元测
相关产品与服务
验证码
腾讯云新一代行为验证码(Captcha),基于十道安全栅栏, 为网页、App、小程序开发者打造立体、全面的人机验证。最大程度保护注册登录、活动秒杀、点赞发帖、数据保护等各大场景下业务安全的同时,提供更精细化的用户体验。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档