依赖注入团结 - 有条件解决 [英] Dependency Injection Unity - Conditional resolving
问题描述
有条件解决的是过去的事情,我不此刻明白
Conditional resolving is the last thing I don't understand at the moment.
假设我们有一个接口IAuthenticate进行的:
Lets say we have an interface IAuthenticate:
public interface IAuthenticate{
bool Login(string user, string pass);
}
现在我有两个类型的身份验证。
Now I have two types of authentication.
微博AUTH
public class TwitterAuth : IAuthenticate
{
bool Login(string user, string pass)
{
//connect to twitter api
}
}
Facebook的身份验证
public class FacebookAuth: IAuthenticate
{
bool Login(string user, string pass)
{
//connect to fb api
}
}
中注册的统一配置类型:
Registering types in unity config:
unityContainer.RegisterType<IAuthenticate, TwitterAuth>();
unityContainer.RegisterType<IAuthenticate, FacebookAuth>();
在我们的控制器通过DI注入对象:
inject objects via DI in our controller:
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);
}
团结究竟如何知道它必须解决不同类型的哪个对象验证?我该怎么做有条件解决这种情况?
How exactly will unity know which object does it have to resolve for different types of authentication? How do I do conditional resolving in this case?
我和我的朋友说话,他解释说,如果这种情况出现是错误的设计,但是这仅仅是工厂模式用了。
I spoke with friend of mine, and he explained if this situation appears it is wrong design, but this is just factory pattern used.
推荐答案
要解决这个问题的简单方法是使用的战略格局。请注意,您可以添加或删除登录提供商在不改变设计 - 你只需要改变DI配置
A simple way to solve this is with the strategy pattern. Note that you can add or remove login providers without changing the design - you simply need to change the DI configuration.
public interface IAuthenticate{
bool Login(string user, string pass);
bool AppliesTo(string providerName);
}
public interface IAuthenticateStrategy
{
bool Login(string providerName, string user, string pass);
}
验证提供商
Authenticate Providers
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);
}
}
策略
Strategy
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);
}
}
统一登记
Unity Registration
// 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")
)
));
用法
Usage
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);
}
这篇关于依赖注入团结 - 有条件解决的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!