依赖注入 Unity 中的条件解析
依赖注入 (DI) 允许将依赖项自动注入到对象中,从而减少手动操作的需要实例化和配置。条件解析是指根据特定条件动态解析接口的不同实现的能力。
问题:
考虑以下场景,其中有两个身份验证提供程序:TwitterAuth 和FacebookAuth,实现 IAuthenticate 接口:
public interface IAuthenticate { bool Login(string user, string pass); } public class TwitterAuth : IAuthenticate { bool Login(string user, string pass) { /* connect to twitter api */ } } public class FacebookAuth : IAuthenticate { bool Login(string user, string pass) { /* connect to fb api */ } }
在控制器中,您想要注入一个基于身份验证提供程序的 IAuthenticate 实现,在本例中由操作方法(例如 Twitter 或 Facebook)确定。
工厂模式作为解决方案:
一种方法是按照您朋友的建议使用工厂模式。但是,这涉及为每个身份验证提供程序创建一个工厂类,从而导致潜在的代码重复和维护问题。
具有条件解析的策略模式:
更灵活的解决方案就是将策略模式与条件结合使用解析:
接口:
public interface IAuthenticate { bool Login(string user, string pass); bool AppliesTo(string providerName); } public interface IAuthenticateStrategy { bool Login(string providerName, string user, string pass); }
验证提供商:
public class TwitterAuth : IAuthenticate { bool Login(string user, string pass) { /* connect to twitter api */ } bool AppliesTo(string providerName) { return this.GetType().Name.Equals(providerName); } } public class FacebookAuth : IAuthenticate { bool Login(string user, string pass) { /* connect to fb api */ } bool AppliesTo(string providerName) { return this.GetType().Name.Equals(providerName); } }
每个提供商都实现 IAuthenticate 并提供确定它是否适用于给定提供者的方法name.
策略:
public class AuthenticateStrategy : IAuthenticateStrategy { private readonly IAuthenticate[] authenticateProviders; public AuthenticateStrategy(IAuthenticate[] authenticateProviders) { this.authenticateProviders = authenticateProviders; } public bool Login(string providerName, string user, string pass) { var provider = authenticateProviders.FirstOrDefault(x => x.AppliesTo(providerName)); if (provider == null) throw new Exception("Login provider not registered"); return provider.Login(user, pass); } }
该策略采用一组 IAuthenticate 提供程序并处理条件解析。它遍历提供者以找到与提供者名称匹配的提供者,并将登录操作委托给它。
Unity 注册:
unityContainer.RegisterType<IAuthenticate, TwitterAuth>("twitterAuth"); unityContainer.RegisterType<IAuthenticate, FacebookAuth>("facebookAuth"); unityContainer.RegisterType<IAuthenticateStrategy, AuthenticateStrategy>( new InjectionConstructor( new ResolvedArrayParameter<IAuthenticate>( new ResolvedParameter<IAuthenticate>("twitterAuth"), new ResolvedParameter<IAuthenticate>("facebookAuth") ) ));
此注册配置 Unity通过提供者名称解析 IAuthenticate 实现并使用这些解析注入 AuthenticateStrategy
用法:
private readonly IAuthenticateStrategy _authenticateStrategy; public AuthenticateController(IAuthenticateStrategy authenticateStrategy) { _authenticateStrategy = authenticateStrategy; } // login with twitter public virtual ActionResult Twitter(string user, string pass) { bool success = _authenticateStrategy.Login("TwitterAuth", user, pass); } // login with fb public virtual ActionResult Facebook(string user, string pass) { bool success = _authenticateStrategy.Login("FacebookAuth", user, pass); }
AuthenticateStrategy 被注入到控制器中,然后控制器根据提供者委托登录操作
优点:
以上是Unity 依赖注入如何处理多个身份验证提供程序的条件解析?的详细内容。更多信息请关注PHP中文网其他相关文章!