<input id="ohw05"></input>
  • <table id="ohw05"><menu id="ohw05"></menu></table>
  • <var id="ohw05"></var>
  • <code id="ohw05"><cite id="ohw05"></cite></code>
    <label id="ohw05"></label>
    <var id="ohw05"></var>
  • .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  閱讀(127)  評論(0編輯  收藏  舉報
    国产美女a做受大片观看