SOf*_*tic 4 c# asp.net-mvc dependency-injection ioc-container abstract-factory
我有以下类和接口结构,我很难尝试让代码完成我需要的工作.
public interface IUserManager
{
int Add(User user);
}
public class UserManagerA : IUserManager{}
public class UserManagerB : IUserManager{}
Run Code Online (Sandbox Code Playgroud)
在这个例子中,我使用Ninject作为IoC容器,但如果其他容器解决了这个问题,我可以更改它:
这是在我的内心NinjectWebCommon.cs:
void RegisterServices(IKernel kernel)
{
string userRole = CurrentUser.Role;//this gets the user logged in
//This is the part I do not how to do
//I wish I could just type this in:
kernel.Bind<IUserManager>().To<UserManagerA>()
.When(userRole == "RoleA"); // this doesn't work obviously
kernel.Bind<IUserManager>().To<UserManagerB>()
.When(userRole == "RoleB"); // same doesn't work
}
Run Code Online (Sandbox Code Playgroud)
所有这一切,以便在我的(MVC)控制器中我可以这样做:
public class UserController
{
private readonly IUserManager _userManager;
public UserController(IUserManager userManager)
{
_userManager = userManager;
}
public ActionResult Add(User user)
{
//this would call the correct manager
//based on the userRole
_userManager.Add(user);
}
}
Run Code Online (Sandbox Code Playgroud)
我一直在阅读有关抽象工厂的文章,但没有找到解释如何将工厂与IoC容器集成并传递在运行时获得的参数来解决实现的文章.
创建一个负责提供正确的类UserManager并将其注入您的控制器:
public class UserManagerProvider : IUserManagerProvider
{
private readonly IContext _context;
public UserManagerProvider(IContext context)
{
_context = context;
}
public IUserManager Create(User currentUser)
{
if (currentUser.Role == "User A")
return _context.Kernel.Get<UserManagerA>();
if (currentUser.Role == "User B")
return _context.Kernel.Get<UserManagerB>();
// Or bind and resolve by name
// _context.Kernel.Get<IUserManager>(currentUser.Role);
}
}
Run Code Online (Sandbox Code Playgroud)
在控制器中:
private readonly IUserManager _userManager;
public UserController(IUserManagerProvider userManagerProvider)
{
_userManager = userManagerProvider.Create(CurrentUser);
}
Run Code Online (Sandbox Code Playgroud)
另外,作为旁注,您应该CurrentUserProvider负责获取当前用户.依赖静态方法会使单元测试变得困难,并且您实际上在所有引用它的类中隐藏了依赖项:
private readonly IUserManager _userManager;
private readonly User _currentUser;
public UserController(IUserManagerProvider userManagerProvider, ICurrentUserProvider currentUserProvider)
{
_currentUser = currentUserProvider.GetUser();
_userManager = userManagerProvider.Create(_currentUser);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
367 次 |
| 最近记录: |