我在使用表单身份验证的MVC4应用程序中使用Autofac作为DI容器。我在控制器的构造函数中注入依赖于IContext
的服务,如下所示:
public MyController(IUserService userService)
{
this.userService = userService;
}
Autofac RegisterDependencies
方法包含以下内容:
var builder = new ContainerBuilder();
builder.RegisterControllers(typeof(MvcApplication).Assembly);
builder.RegisterType<MyDbContext>()
.As<IContext>()
.InstancePerRequest();
builder.RegisterType<UserService>()
.As<IUserService>;
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
当用户登录时,会注入UserService
IUserService
的实现。现在,我希望为未登录的用户IUserService
实现不同的AnonymousService
实现:AnonymousService
。
如果用户未登录,是否可以通过Autofac
注入UserService
,如果用户已登录,是否有{{1}}?
答案 0 :(得分:3)
我认为这种情况是使用此处记录的密钥服务的理想选择
http://docs.autofac.org/en/latest/advanced/keyed-services.html
您只有两种可能的服务实现,因此您只需要定义两个值枚举:
public enum AuthenticatedStatusEnum
{
Anonymous,
Authenticated
}
并注册您的服务(让我们说IUserNameRetriever)两次,一次为foreach枚举值:
builder.RegisterType<AnonymousUserNameRetriever>().Keyed<IUserNameRetriever>(AuthenticatedStatusEnum.Anonymous);
builder.RegisterType<AuthenticatedNameRetriever>().Keyed<IUserNameRetriever>(AuthenticatedStatusEnum.Authenticated);
您的控制器将以这种方式定义:
public class HomeController : Controller
{
IUserNameRetriever _currentUserNameRetriever;
public HomeController(IIndex<AuthenticatedStatusEnum, IUserNameRetriever> userNameRetrievers)
{
_currentUserNameRetriever = _userNameRetrievers[AuthenticatedStatus];
}
AuthenticatedStatusEnum AuthenticatedStatus
{
get
{
return System.Threading.Thread.CurrentPrincipal.Identity.IsAuthenticated ? AuthenticatedStatus.Authenticated : AuthenticatedStatus.Anonymous;
}
}
_currentUserNameRetriever服务将根据用户的身份验证状态具有正确的实现。
P.S。在实际应用程序中,您通常会从另一个注入的服务中获取AuthenticatedStatus值。