ame*_*els 14 c# dependency-injection inversion-of-control unity-container
有条件的解决是目前我还不了解的最后一件事.
让我们说我们有一个界面IAuthenticate:
public interface IAuthenticate{
bool Login(string user, string pass);
}
Run Code Online (Sandbox Code Playgroud)
现在我有两种类型的身份验证.
Twitter认证
public class TwitterAuth : IAuthenticate
{
bool Login(string user, string pass)
{
//connect to twitter api
}
}
Run Code Online (Sandbox Code Playgroud)
Facebook Auth
public class FacebookAuth: IAuthenticate
{
bool Login(string user, string pass)
{
//connect to fb api
}
}
Run Code Online (Sandbox Code Playgroud)
在unity配置中注册类型:
unityContainer.RegisterType<IAuthenticate, TwitterAuth>();
unityContainer.RegisterType<IAuthenticate, FacebookAuth>();
Run Code Online (Sandbox Code Playgroud)
在我们的控制器中通过DI注入对象:
private readonly IAuthenticate _authenticate;
public AuthenticateController(IAuthenticate authenticate)
{
_authenticate = authenticate;
}
// login with twitter
public virtual ActionResult Twitter(string user, string pass)
{
bool success =
_authenticate.Login(user, pass);
}
// login with fb
public virtual ActionResult Facebook(string user, string pass)
{
bool success =
_authenticate.Login(user, pass);
}
// login with google
public virtual ActionResult Google(string user, string pass)
{
bool success =
_authenticate.Login(user, pass);
}
Run Code Online (Sandbox Code Playgroud)
团结如何知道它必须为不同类型的身份验证解决哪个对象?在这种情况下如何进行条件解决?
我和我的朋友谈过,他解释说如果这种情况出现是错误的设计,但这只是工厂模式使用的.
Nig*_*888 40
解决此问题的一种简单方法是使用策略模式.请注意,您可以在不更改设计的情况下添加或删除登录提供程序 - 您只需更改DI配置即可.
public interface IAuthenticate{
bool Login(string user, string pass);
bool AppliesTo(string providerName);
}
public interface IAuthenticateStrategy
{
bool Login(string providerName, string user, string pass);
}
Run Code Online (Sandbox Code Playgroud)
public class TwitterAuth : IAuthenticate
{
bool Login(string user, string pass)
{
//connect to twitter api
}
bool AppliesTo(string providerName)
{
// I used the type name for this example, but
// note that you could use any string or other
// datatype to select the correct provider.
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);
}
}
Run Code Online (Sandbox Code Playgroud)
public class AuthenticateStrategy: IAuthenticateStrategy
{
private readonly IAuthenticate[] authenticateProviders;
public AuthenticateStrategy(IAuthenticate[] authenticateProviders)
{
if (authenticateProviders == null)
throw new ArgumentNullException("authenticateProviders");
this.authenticateProviders = authenticateProviders;
}
public bool Login(string providerName, string user, string pass)
{
var provider = this.authenticateProviders
.FirstOrDefault(x => x.AppliesTo(providerName));
if (provider == null)
{
throw new Exception("Login provider not registered");
}
return provider.Login(user, pass);
}
}
Run Code Online (Sandbox Code Playgroud)
// Note that the strings used here for instance names have nothing
// to do with the strings used to select the instance in the strategy pattern
unityContainer.RegisterType<IAuthenticate, TwitterAuth>("twitterAuth");
unityContainer.RegisterType<IAuthenticate, FacebookAuth>("facebookAuth");
unityContainer.RegisterType<IAuthenticateStrategy, AuthenticateStrategy>(
new InjectionConstructor(
new ResolvedArrayParameter<IAuthenticate>(
new ResolvedParameter<IAuthenticate>("twitterAuth")
),
new ResolvedArrayParameter<IAuthenticate>(
new ResolvedParameter<IAuthenticate>("facebookAuth")
)
));
Run Code Online (Sandbox Code Playgroud)
private readonly IAuthenticateStrategy _authenticateStrategy;
public AuthenticateController(IAuthenticateStrategy authenticateStrategy)
{
if (authenticateStrategy == null)
throw new ArgumentNullException("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);
}
Run Code Online (Sandbox Code Playgroud)
团结不会没有你的帮助.您可以在注册IAuthenticate类型时提供名称:
unityContainer.RegisterType<IAuthenticate, TwitterAuth>("Twitter");
unityContainer.RegisterType<IAuthenticate, FacebookAuth>("Facebook");
Run Code Online (Sandbox Code Playgroud)
您将不再希望将IAuthenticate实例直接注入AuthenticateController.您将根据一致的条件(服务定位器样式)获得所需的实例:
myContainer.Resolve<IAuthenticate>("Twitter");
Run Code Online (Sandbox Code Playgroud)
或者你会注入一个为你做这个的工厂(如果你喜欢严格的DI风格).
| 归档时间: |
|
| 查看次数: |
10313 次 |
| 最近记录: |