• .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容器中获取注入的实例,所以之前的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);
    }
    
  • 相关阅读:
    nginx 的使用
    虹科方案 | 虹科基于空口测试的新型5G毫米波测试方案
    Go 中channel/goroutine实现并发和并行
    知网中的硕博论文是caj格式,如何用CAJ转PDF?
    OFDM深入学习及MATLAB仿真
    华为数通方向HCIP-DataCom H12-831题库(单选题:161-180)
    Vue学习笔记之Vuex 6.25
    K-Means算法进行分类
    videoPlayer的播放
    (※)力扣刷题-字符串-实现 strStr()(KMP算法)
  • 原文地址:https://www.cnblogs.com/inday/p/asp-net-core-factory.html