Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 有人能解释一下棱镜';s决心<&燃气轮机;方法?_Wpf_Inversion Of Control_Unity Container_Prism_Containers - Fatal编程技术网

Wpf 有人能解释一下棱镜';s决心<&燃气轮机;方法?

Wpf 有人能解释一下棱镜';s决心<&燃气轮机;方法?,wpf,inversion-of-control,unity-container,prism,containers,Wpf,Inversion Of Control,Unity Container,Prism,Containers,我有一个带有以下Initialize()方法的CustomersModule.cs: TestWhatever类只是我创建的一个虚拟类: public class TestWhatever { public string Title { get; set; } public TestWhatever() { Title = "this is the title"; } } 尽管容器从未注册过它,但它还是愉快地解析了CustomerPresen

我有一个带有以下Initialize()方法的CustomersModule.cs

TestWhatever类只是我创建的一个虚拟类:

public class TestWhatever
{
    public string Title { get; set; }

    public TestWhatever()
    {
        Title = "this is the title";
    }

}
尽管容器从未注册过它,但它还是愉快地解析了
CustomerPresenter
,而且容器不知何故找到了TestAnswer,实例化了它,并将它注入
CustomerPresenter

我很惊讶地意识到这一点,因为我在Prism文档中找不到任何明确说明容器是如此自动化的地方


这很好,但是容器还有什么我不知道的,也就是说,它还能做什么我不知道的例如,我可以从其他模块中注入类吗?如果模块碰巧被加载,容器将注入它们,如果没有,它将注入null?

没有什么神奇的事情发生。您正在指定具体的类型,因此它们自然是可解析的,因为如果我们有
Type
对象,我们可以对其调用构造函数

class Fred { };

Fred f1 = new Fred();

Type t = typeof(Fred);

Fred f2 = (Fred)t.GetConstructor(Type.EmptyTypes).Invoke(null);
上面的最后一行实际上是发生了什么,类型t是通过在您给
Resolve
的类型参数上使用
typeof
找到的

如果类型不能由new构造(因为它位于未知的单独代码库中),那么您将无法将其作为类型参数提供给
Resolve

在第二种情况下,它是构造函数注入,但它仍然是一种已知的具体可构造类型。通过反射,Unity框架可以向构造函数获取所有类型参数的数组。类型
testwhere
是可构造的,因此对于构造什么没有歧义或困难

至于您对单独模块(程序集)的担忧,如果您将
testwhater
移动到另一个程序集,则不会更改您编写的代码行;这只意味着您必须添加对另一个程序集的引用才能生成这个程序集。然后,
TestWhatever
仍然是一个明确的引用可构造类型,因此它可以由Unity构造

换句话说,如果您可以在代码中引用类型,您可以得到一个
type
对象,因此在运行时它将是可直接构造的

评论回复:

如果删除类
TestWhatever
,您将得到一个编译时错误,因为您在代码中引用了该类型。因此,这样做不可能获得运行时


在这种安排中,解耦仍然有效,因为您可以注册
TestWhatever
的特定实例,因此对
Resolve()
的每次调用都将获得相同的实例,而不是构造一个新实例。

没有什么神奇的事情发生。您正在指定具体的类型,因此它们自然是可解析的,因为如果我们有
Type
对象,我们可以对其调用构造函数

class Fred { };

Fred f1 = new Fred();

Type t = typeof(Fred);

Fred f2 = (Fred)t.GetConstructor(Type.EmptyTypes).Invoke(null);
上面的最后一行实际上是发生了什么,类型t是通过在您给
Resolve
的类型参数上使用
typeof
找到的

如果类型不能由new构造(因为它位于未知的单独代码库中),那么您将无法将其作为类型参数提供给
Resolve

在第二种情况下,它是构造函数注入,但它仍然是一种已知的具体可构造类型。通过反射,Unity框架可以向构造函数获取所有类型参数的数组。类型
testwhere
是可构造的,因此对于构造什么没有歧义或困难

至于您对单独模块(程序集)的担忧,如果您将
testwhater
移动到另一个程序集,则不会更改您编写的代码行;这只意味着您必须添加对另一个程序集的引用才能生成这个程序集。然后,
TestWhatever
仍然是一个明确的引用可构造类型,因此它可以由Unity构造

换句话说,如果您可以在代码中引用类型,您可以得到一个
type
对象,因此在运行时它将是可直接构造的

评论回复:

如果删除类
TestWhatever
,您将得到一个编译时错误,因为您在代码中引用了该类型。因此,这样做不可能获得运行时


解耦在这种安排中仍然有效,因为您可以注册
TestWhatever
的特定实例,因此对
Resolve()
的每次调用都将获得相同的实例,而不是构造一个新的实例。

之所以有效,是因为Unity是为它设计的。当您使用具体类型解析时,Unity会查看它是否可以从容器解析。如果不能,那么它只是去实例化类型,解析它的依赖项。这真的很简单。

之所以有效,是因为Unity就是为它而设计的。当您使用具体类型解析时,Unity会查看它是否可以从容器解析。如果不能,那么它只是去实例化类型,解析它的依赖项。这真的很简单。

但是解耦从何而来,例如,如果我需要一个来自另一个模块的类“MenuManager”,并且该模块没有被加载,我理解容器应该(例如)注入一个null,以便应用程序可以在有或没有其他部分的情况下运行,但是如果我(例如)删除类“testwhatch”应用程序出现错误。请思考:如何指定要创建的菜单管理器?在CLR执行类似于
Resolve()的表达式之前它必须加载包含菜单管理器定义的程序集。如果你提到
class Fred { };

Fred f1 = new Fred();

Type t = typeof(Fred);

Fred f2 = (Fred)t.GetConstructor(Type.EmptyTypes).Invoke(null);