【发布时间】:2014-04-01 17:41:53
【问题描述】:
它是一个桌面应用程序,在访问底层数据源时必须模拟当前用户。
如何告诉 Ninject 在父对象的属性不为空之前不要绑定依赖项?
- 应用程序在启动时强制进行用户身份验证
- 一旦通过身份验证,对当前用户凭据的引用将保存在
IMembershipService中 - 访问底层数据源需要对用户进行身份验证,以便commection 字符串说明要模拟的凭据
我实际使用的是 NHibernate,我需要根据身份验证时提供的用户凭据动态创建连接字符串。
所以我想实现:
public class DataModule : NinjectModule {
public override void Load() {
Bind<ISessionFactory>().ToProvider<SessionFactoryProvider>()
.When( // IMembershipService.CurrentUser != null );
}
}
由于SessionProviderFactory 依赖于IMembershipService.CurrentUser。
我知道这可能不是世纪设计,除了我现在需要它以这种方式工作,以便我可以交付我的潜在可交付产品。之后我很乐意重构。
SessionFactoryProvider
public class SessionFactoryProvider : Provider<ISessionFactory> {
public class SessionFactoryProvider(IMembershipService service) {
membershipService = service;
}
protected override ISessionFactory CreateInstance(IContext context) {
Configuration nhconfig = new Configuration().Configure();
nhconfig.AddAssembly(Assembly.GetExecutingAssembly());
nhconfig.Properties["connection.connection_string"] = buildConnectiongString();
return nhconfig.BuildSessionFactory();
}
private string buildConnectionString() {
return string.Format(membershipService.GetDefaultConnectionString()
, membershipService.CurrentUser.DatabaseInstanceName
, membershipService.CurrentUser.Login
, membershipService.CurrentUser.Password);
}
private readonly IMembershipService membershipService;
}
会话提供者
public class SessionProvider : Provider<ISession> {
public class SessionProvider(ISessionFactory factory) {
sessionFactory = factory;
}
protected override ISession CreateInstance(IContext context) {
return sessionFactory.OpenSession();
}
private readonly ISessionFactory sessionFactory;
}
事实是我无法在应用程序启动时实例化IMembershipService.CurrentUser。用户必须首先对系统进行身份验证,因此ActivationException。
激活 ISession 时出错
没有匹配的绑定可用,并且类型不是自绑定的。
激活路径:
3) 将依赖ISession注入到InquiriesRepository类型的构造函数的参数session中
2) 将依赖 IInquiriesRepository 注入到 InquiriesManagementPresenter 类型的构造函数的参数存储库中
1) 请求 InquiriesManagementPresenter
建议:
1) 确保您已为 ISession 定义绑定。
2) 如果绑定是在模块中定义的,请确保该模块已加载到内核中。
3) 确保您没有意外创建多个内核。
4) 如果您使用构造函数参数,请确保参数名称与构造函数参数名称匹配。
5) 如果您使用自动模块加载,请确保搜索路径和过滤器正确。
那么,我该怎么做呢?
欢迎提出任何设计改进建议。但请记住,我需要它才能很好地工作。我会为下一次交付重构。
编辑
看起来我也许可以使用上下文/范围依赖注入。
How to use the additional Ninject Scopes of NamedScope
而且,我仍然无法弄清楚如何让它在我的场景中工作。
更新
通过阅读,我开始怀疑上下文绑定是否比条件绑定更适合我的需求。
有什么想法吗?
每篇与条件绑定相关的文章都在讨论条件类型绑定,而不是条件状态绑定。
在我的场景中,它特别认为它是一个条件状态绑定,因此有关于上下文绑定的想法。
然后,我会有两个绑定。
- 用户通过身份验证之前
- 用户通过身份验证后
所以也许我要么必须使用延迟注入,这可以解决我的问题,因为在应用程序启动时不需要 ISessionFactory 的实例。
我有点迷茫了……
【问题讨论】:
-
仅当运行它所需的一切都可用时才使用
Lazy<ISession>注入或创建实例。另一种方法是代理ISession并在底层实现可用时交换它。如果在会话可用之前调用代理,则抛出异常。但我认为我宁愿只在所需的一切可用时构建对象树的受影响路径。
标签: c# nhibernate dependency-injection ninject conditional-binding