Ninject 不会解决 WPF 中的构造函数注入
Ninject won't resolve constructor injection in WPF
我的 WPF 桌面应用程序正在尝试使用 Ninject 注入一些接口依赖项,如下所示。应用程序启动看起来像这样,(我认为)自动生成:
void App_Startup(object sender, StartupEventArgs e)
{
IKernel _Kernel = new StandardKernel();
_Kernel.Load(Assembly.GetExecutingAssembly());
}
然后我有一个 NinjectModel
-extending class 上面调用了它的 Load 方法,绑定是这样发生的:
Bind<Inheritance.IWindowProvider>().To<WindowProvider>().InSingletonScope();
然后我的视图模型接受 IWindowProvider
,在这种情况下,我还添加了 [Inject]
属性。
[Inject]
public LoginDetailsVM (IWindowProvider windowProvider) {
this.WindowProvider = windowProvider;
}
在其他地方 然后(在另一个 VM 中),我想创建此视图模型的实例:
IKernel kernel = new StandardKernel();
LoginDetailsVM loginDetails = kernel.Get<LoginDetailsVM>();
但是我得到 "dreaded" 错误:
Error activating IWindowProvider
No matching bindings are available,
and the type is not self-bindable.
我最初的搜索发现我实例化 StandardKernel
两次可能是问题所在,但我不确定如何访问它。
肯定必须绕过内核实例在某种程度上破坏了注入的要点之一?
此外,显式 Get<T>()
形式是获取实例的公认选择,还是有更好的隐式方法来调用注入的构造函数?
抱歉,我的理解似乎很天真,我对 Ninject 和一般 DI 完全陌生。
问题不是在内核中传递——而是你访问它的地方。如果您在组合根 (App_Startup
) 之外引用它,那么创建一个新的并不比传递您已经创建的那个更好。
当您需要在组合根之外解决某些问题并且不想引用容器时,一种解决方案是创建一个工厂。您需要解决某些问题的组件不会向容器请求 - 它会向工厂请求。
反过来,设置工厂从容器中解析它。但那是在你的组合根中设置的,工厂可以替换为不涉及容器的实现。所以你仍然可以说你的组件不依赖于容器或与容器对话。
Here's some documentation 关于配置 Ninject 以向工厂提供实例。
将 IOC 容器想象成一个魔法字典,其中存储了类型和对象实例。
如果你这样做了
Void a method (){
Var dictionary = new dictionary ();
dictionary.Add(typeof(IFOO), new Foo());
}
Void other_method(){
Var dictionary = new dictionary ();
IFOO instance =Dictionary[typeof(IFOO)];
// would you expect this to work?
}
单例模式通常用于提供对 IOC 容器的访问。
我的 WPF 桌面应用程序正在尝试使用 Ninject 注入一些接口依赖项,如下所示。应用程序启动看起来像这样,(我认为)自动生成:
void App_Startup(object sender, StartupEventArgs e)
{
IKernel _Kernel = new StandardKernel();
_Kernel.Load(Assembly.GetExecutingAssembly());
}
然后我有一个 NinjectModel
-extending class 上面调用了它的 Load 方法,绑定是这样发生的:
Bind<Inheritance.IWindowProvider>().To<WindowProvider>().InSingletonScope();
然后我的视图模型接受 IWindowProvider
,在这种情况下,我还添加了 [Inject]
属性。
[Inject]
public LoginDetailsVM (IWindowProvider windowProvider) {
this.WindowProvider = windowProvider;
}
在其他地方 然后(在另一个 VM 中),我想创建此视图模型的实例:
IKernel kernel = new StandardKernel();
LoginDetailsVM loginDetails = kernel.Get<LoginDetailsVM>();
但是我得到 "dreaded" 错误:
Error activating IWindowProvider
No matching bindings are available, and the type is not self-bindable.
我最初的搜索发现我实例化 StandardKernel
两次可能是问题所在,但我不确定如何访问它。
肯定必须绕过内核实例在某种程度上破坏了注入的要点之一?
此外,显式 Get<T>()
形式是获取实例的公认选择,还是有更好的隐式方法来调用注入的构造函数?
抱歉,我的理解似乎很天真,我对 Ninject 和一般 DI 完全陌生。
问题不是在内核中传递——而是你访问它的地方。如果您在组合根 (App_Startup
) 之外引用它,那么创建一个新的并不比传递您已经创建的那个更好。
当您需要在组合根之外解决某些问题并且不想引用容器时,一种解决方案是创建一个工厂。您需要解决某些问题的组件不会向容器请求 - 它会向工厂请求。
反过来,设置工厂从容器中解析它。但那是在你的组合根中设置的,工厂可以替换为不涉及容器的实现。所以你仍然可以说你的组件不依赖于容器或与容器对话。
Here's some documentation 关于配置 Ninject 以向工厂提供实例。
将 IOC 容器想象成一个魔法字典,其中存储了类型和对象实例。
如果你这样做了
Void a method (){
Var dictionary = new dictionary ();
dictionary.Add(typeof(IFOO), new Foo());
}
Void other_method(){
Var dictionary = new dictionary ();
IFOO instance =Dictionary[typeof(IFOO)];
// would you expect this to work?
}
单例模式通常用于提供对 IOC 容器的访问。