这是一个桌面应用程序,在访问基础数据源时必须模拟当前用户。
如果父对象的属性不为null,我怎么能告诉Ninject不绑定依赖项?
IMembershipService
我实际上正在使用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;
}
SessionProvider
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
类型的构造函数的参数会话中2)将依赖关系IInquiriesRepository注入到InquiriesManagementPresenter类型的构造函数的参数存储库中
1)要求InquiriesManagementPresenter
建议:
1)确保您已为ISession定义了绑定。
2)如果在模块中定义了绑定,请确保已将模块加载到内核中。
3)确保您没有意外创建多个内核。
4)如果使用构造函数参数,请确保参数名称与构造函数参数名称匹配。
5)如果使用自动模块加载,请确保搜索路径和过滤器正确无误。
那么,我该怎么做呢?
欢迎任何设计改进建议。但请记住,我需要它才能正常工作。我将为下一次交付重构。
修改
看起来我可能会使用上下文/范围依赖注入。
How to use the additional Ninject Scopes of NamedScope
但是,我仍然无法弄清楚如何在我的场景中使它工作。
更新
通过我的阅读,我开始怀疑,与条件约束相比,上下文绑定可能更适合我的需要。
有什么想法吗?
与条件绑定相关的每篇文章都讨论条件类型绑定,而不是条件状态绑定。
在我的场景中,它特别相信它是一个条件状态绑定,因此关于上下文绑定的想法。
然后,我会有两个绑定。
所以也许我要么使用延迟注入,这会解决我的问题,因为应用程序启动时不需要ISessionFactory
的实例。
我在这里有点失落......
答案 0 :(得分:3)
您可以创建条件绑定:
IBindingRoot.Bind<IFoo>().To<Foo>()
.When(request => request.ParentContext.Kernel.Get<IUserService>().AuthenticatedUser != null);
但我不推荐它; - )
@Pacane
每次请求IFoo时都会执行When条件。它转化为另一个请求,因此成本很高。
此外,此方法仅在有父请求的情况下有效。如果您执行IResolutionRoot.Get<IFoo>()
,则会抛出NullReferenceException
。
您可以通过访问语法提供的内核来解决这个问题。但我不知道它是否会在未来版本的ninject中留在那里......
此外,还有一个应用程序引导机制,可以确保您在完全初始化之后只实例化对象树的某些部分。 (=&gt; authenticated)是一个更好的设计。至少在我看来。