问题描述
|
我有这个界面:
public interface IUserProfileService
{
// stuff
}
实施者:
public class UserProfileService : IUserProfileService
{
private readonly string m_userName;
public UserProfileService(string userName)
{
m_userName = userName;
}
}
我需要将其注入这样的控制器中:
public class ProfilesController : BaseController
{
private readonly IUserProfileService m_profileService;
public ProfilesController(IUserProfileService profileService)
{
m_profileService = profileService;
}
}
我不知道如何将该接口及其实现注册到Ninject容器中,以便当Ninject初始化此服务的实例时传递userName参数。
有什么想法可以实现这一目标吗?
解决方法
一种选择是注入工厂并使用
Create(string userName)
创建您的依赖项。
public class UserProfileServiceFactory
{
public IUserProfileService Create(string userName)
{
return new UserProfileService(userName);
}
}
似乎不得不创建另一个类,但是当“ 5”加入了附加的依赖关系时,好处通常会出现。
, 技术上的ninject答案是使用构造函数参数,如下所示:
Bind<IUserProfileService>().To<UserProfileService>().WithConstructorArgument(\"userName\",\"karl\");
当然,您需要弄清楚“ karl”的来源。这确实取决于您的应用程序。也许它是一个Web应用程序,并且在HttpContex上?我不知道。如果变得相当复杂,则可能需要编写IProvider而不是进行常规绑定。
, 诀窍是不要在该类中注入用户名。您将此类称为服务,因此它可能可与多个用户透明地工作。我看到两种解决方案:
向代表当前用户的服务中注入抽象:
public class UserProfileService : IUserProfileService
{
private readonly IPrincipal currentUser;
public UserProfileService(IPrincipal currentUser)
{
this.currentUser = currentUser;
}
void IUserProfileService.SomeOperation()
{
var user = this.currentUser;
// Do some nice stuff with user
}
}
创建特定于您正在使用的技术的实现,例如:
public class AspNetUserProfileService : IUserProfileService
{
public AspNetUserProfileService()
{
}
void IUserProfileService.SomeOperation()
{
var user = this.CurrentUser;
// Do some nice stuff with user
}
private IPrincipal CurrentUser
{
get { return HttpContext.Current.User; }
}
}
如果可以,请选择选项一。