.NetCore中使用工厂模式

博客 动态
0 126
优雅殿下
优雅殿下 2022-06-25 11:00:56
悬赏:0 积分 收藏

.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);}
posted @ 2022-06-25 10:48 James.Ying 阅读(0) 评论(0) 编辑 收藏 举报
回帖
    优雅殿下

    优雅殿下 (王者 段位)

    2018 积分 (2)粉丝 (47)源码

    小小码农,大大世界

     

    温馨提示

    亦奇源码

    最新会员