.Net Core 中使用工厂模式

打印 上一主题 下一主题

主题 532|帖子 532|积分 1596

什么是工厂模式

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

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

当一个抽象类有多个实现的时候,需要多次实例化的时候,就要考虑使用工厂模式。
比如:登录的抽象类ILoginBusiness,它有2个实现,一个用用户名密码登录,一个用手机号验证码登录
  1. public interface ILoginBusiness
  2. {
  3.     Task Login(LoginInputDTO input);
  4. }
  5. public class MobileCodeLogin : ILoginBusiness
  6. {
  7.     public Task Login(LoginInputDTO input)
  8.     {
  9.         // todo
  10.     }
  11. }
  12. public class UserNameAndPasswordLogin : ILoginBusiness
  13. {
  14.     public Task Login(LoginInputDTO input)
  15.     {
  16.         // todo
  17.     }
  18. }
复制代码
按照原有方式,我们会根据某个条件去实例化,比如loginType
  1. ILoginBusiness loginBusiness;
  2. if (loginType == 1)
  3. {
  4.     loginBusiness = new MobileCodeLogin();
  5. }
  6. else
  7. {
  8.     loginBusiness = new UserNameAndPasswordLogin()
  9. }
复制代码
当有多种实例的话,就需要更多的ifelse或者switch,工厂模式的作用就是把这种建造对象的方法放在工厂类去解决,统一管理统一维护。
实现方式
  1. public interface ILoginFactory
  2. {
  3.     ILoginBusiness Create(LoginInputDTO inputDto);
  4. }
  5. public class LoginFactory : BaseBusiness, ILoginFactory, ITransientDependency
  6. {
  7.    
  8.     public ILoginBusiness Create(LoginInputDTO inputDto)
  9.     {
  10.         return inputDto.LoginType == LoginType.UserNameAndPwd
  11.             ? AppDependencyResolver.Current.GetService<UserNameAndPwdLogin>()
  12.             : (ILoginBusiness)AppDependencyResolver.Current.GetService<MobileCodeLogin>();
  13.     }
  14.     public LoginFactory(IRepository repository) : base(repository)
  15.     {
  16.         
  17.     }
  18. }
复制代码
如果用new的方法去实例化,就需要把构造方法中的参数在工厂的构造方法里也加入进去,所以这里用了一个AppDependencyResolver,这里的AppDependencyResolver.Current.GetService是从当前IOC容器中获取注入的实例,所以之前的MobileCodeLogin和UserNameAndPasswordLogin需要注入到IOC实例中,在我们项目就是继承ITransientDependency
  1. public class AppDependencyResolver
  2. {
  3.     private static AppDependencyResolver _resolver;
  4.     public static AppDependencyResolver Current
  5.     {
  6.         get
  7.         {
  8.             if (_resolver == null)
  9.                 throw new Exception("AppDependencyResolver not initialized");
  10.             return _resolver;
  11.         }
  12.     }
  13.    
  14.     // 在startUp的ConfigureService的最后,加入AppDependencyResolver.Init(services.BuildServiceProvider());
  15.     public static void Init(IServiceProvider service)
  16.     {
  17.         _resolver = new AppDependencyResolver(service);
  18.     }
  19.     private AppDependencyResolver(IServiceProvider serviceProvider)
  20.     {
  21.         _serviceProvider = serviceProvider;
  22.     }
  23.     private readonly IServiceProvider _serviceProvider;
  24.     public object GetService(Type serviceType)
  25.     {
  26.         return _serviceProvider.GetService(serviceType);
  27.     }
  28.     public T GetService<T>()
  29.     {
  30.         return _serviceProvider.GetService<T>();
  31.     }
  32. }
复制代码
关于工厂的单元测

关于工厂,我们只需要测返回的对象是否是我们需要的就可以了,至于对象的执行对不对不需要关心
  1. [Theory(DisplayName = "测试登录工厂")]
  2. [InlineData(LoginType.MobileCode, typeof(MobileCodeLogin))]
  3. [InlineData(LoginType.UserNameAndPwd, typeof(UserNameAndPwdLogin))]
  4. public void CreateTests(LoginType loginType, Type expectedType)
  5. {
  6.     Mock<IRepository> mock = new Mock<IRepository>();
  7.     ILoginFactory factory = new LoginFactory(mock.Object);
  8.     var login =  factory.Create(new LoginInputDTO()
  9.     {
  10.         LoginType = loginType
  11.     });
  12.     Assert.IsType(expectedType, login);
  13. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

半亩花草

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表