是否可以根据用户是否登录向控制器注入不同的服务?
Is it possible to inject different service into controller based on if user is logged in or not?
我在具有表单身份验证的 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));
当用户登录时,IUserService
的 UserService
实现被注入。现在我想对未登录的用户 IUserService
进行不同的实现:AnonymousService
。
有没有办法在用户未登录时通过 Autofac
注入 AnonymousService
并在用户登录时通过 UserService
注入?
我认为这种情况非常适合使用此处记录的键控服务
http://docs.autofac.org/en/latest/advanced/keyed-services.html
该服务只有两种可能的实现方式,因此您只需定义一个具有两个值的枚举:
public enum AuthenticatedStatusEnum
{
Anonymous,
Authenticated
}
并注册您的服务(假设是 IUserNameRetriever)两次,一次是针对每个枚举值:
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 值。
我在具有表单身份验证的 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));
当用户登录时,IUserService
的 UserService
实现被注入。现在我想对未登录的用户 IUserService
进行不同的实现:AnonymousService
。
有没有办法在用户未登录时通过 Autofac
注入 AnonymousService
并在用户登录时通过 UserService
注入?
我认为这种情况非常适合使用此处记录的键控服务
http://docs.autofac.org/en/latest/advanced/keyed-services.html
该服务只有两种可能的实现方式,因此您只需定义一个具有两个值的枚举:
public enum AuthenticatedStatusEnum
{
Anonymous,
Authenticated
}
并注册您的服务(假设是 IUserNameRetriever)两次,一次是针对每个枚举值:
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 值。