Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.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
C# 4.0 SimpleIoc-它能在每次需要时提供新实例吗?_C# 4.0_Mvvm_Mvvm Light_Silverlight 5.0 - Fatal编程技术网

C# 4.0 SimpleIoc-它能在每次需要时提供新实例吗?

C# 4.0 SimpleIoc-它能在每次需要时提供新实例吗?,c#-4.0,mvvm,mvvm-light,silverlight-5.0,C# 4.0,Mvvm,Mvvm Light,Silverlight 5.0,据我所知,SimpleIoc使用GetInstance方法检索已注册类的实例。如果实例不存在,它将创建它。然而,这个实例是缓存的,并且总是被检索的,这模仿了单例模式 我的想法是,如果该ViewModel需要两次的可能性很小,则不需要在内存中保留ViewModel的实例,因此我希望在每次需要时都创建它的新实例。如果我们有ViewModels工厂,我们将有如下属性: public MyViewMOdel MyViewModel { get { return SimpleIoc.Default

据我所知,SimpleIoc使用GetInstance方法检索已注册类的实例。如果实例不存在,它将创建它。然而,这个实例是缓存的,并且总是被检索的,这模仿了单例模式

我的想法是,如果该ViewModel需要两次的可能性很小,则不需要在内存中保留ViewModel的实例,因此我希望在每次需要时都创建它的新实例。如果我们有ViewModels工厂,我们将有如下属性:

public MyViewMOdel MyViewModel
{
    get { return SimpleIoc.Default.GetInstance<MyViewModel>(); }
}
公共MyViewMOdel MyViewMOdel
{
获取{return SimpleIoc.Default.GetInstance();}
}
这一个使用单例模式,我认为这不是所有情况下的最佳实践。为了避免这个问题,我这样做:

public MyViewModel MyViewModel
{
    get { return new MyViewModel(SimpleIoc.Default.GetInstance<ISomeInterface>()); }
}
公共MyViewModel MyViewModel
{
获取{返回新的MyViewModel(SimpleIoc.Default.GetInstance());}
}
这一个有一个缺点,如果我更改MyViewModel的构造函数,我也需要更新这个属性。没什么大不了的,但还是有某种依赖性

你是如何处理这种情况的,我有什么遗漏吗?以及决定不返回非共享实例的原因


另一个问题是,在MVVM深入会话中,Laurent在注册一个特定的ViewModel之后立即使用GetInstance方法,正如他所说的,为了确保容器中已经有这个ViewModel的实例。为什么这是必要的?如果要通过ViewModelLocator获取ViewModel,则将在需要时创建它。那我为什么要提前创建它们呢?

SimpleIOC就是这样。。。一个简单的IOC容器。它会有一些缺点。。。但您不受此限制,您可以始终使用另一个ICO容器(例如Unity、Autofac、Castle等)

就像他模仿他的SimpleIOC一样。他还提到,这是他灵感的来源


但是,请记住,您不一定要将安全容器与MVVM一起使用。在我的几个项目中,我使用了Unity,但每一个其他IOC容器都会同样好,这是一个需求、客户偏好的问题,如果其他一切都失败了,那么这是一个普通的老个人兴趣。

通过向GetInstance方法传递不同的键,每次都可以获得不同的实例。但是,实例将被缓存,因此如果不想将它们保留在缓存中,则需要使用相应的密钥调用Unregister

在演示中,我预先创建VM,因为MainVM向SecondaryVM发送消息。由于Messenger的注册是在SecondaryVm的构造函数中完成的,因此需要先创建它,然后才能开始接收消息。Messenger非常好,因为它是非常解耦的,但是在这种情况下,您需要做额外的工作来补偿解耦:SecondaryVM是消息的目标,即使MainVM没有得到任何对它的引用

希望它有意义。 干杯
Laurent

在与SimpleIoC搏斗以在每次请求特定类型时提供新实例,并发现此功能未实现后(上面接受的基于键的方法不适合您想说的场景,即每次执行数据库操作并丢弃连接),我提出了一个相对体面的解决方案,将IoC与工厂模式相结合: 创建一个类,该类负责通过函数实例化特定类型的新实例:

class MyObjectFactory: IMyObjectFactory
{
    public MyObject CreateObject()
    {
        return new MyObject();
    }
}
为MyObject工厂类创建接口:

public interface IMyObjectFactory
{
    MyObject CreateObject();
}
然后配置IoC容器,以便为使用MyObject实例的任何类提供工厂:

SimpleIoc.Default.Register<IMyObjectFactory, MyObjectFactory>();

通过这种方式,我认为您不受工厂模式的限制,并且拥有IoC容器和构造函数注入的所有好处,同时也绕过了SimpleIoC的限制。

阅读所有内容后,非常有教育意义和高质量的回答在这篇文章中,我只想指出一些可能在技术上不太先进的东西,但我认为将其放在定制
IoC容器
的文章中非常重要:我认为编写您自己的IoC容器是我自己的图书馆相关任务中最简单的一项哦,我确信这在教育上是有价值的。我不在这里放任何教程,因为希望每个读过我观点的人都知道
谷歌搜索
或类似工具;-)

您好,Laurent,在非共享实例的情况下,您是否使用键并不重要(我假设我们不会同时拥有同一视图的多个实例)。在这两种情况下,我都需要注册/注销viewmodel,因此我需要跟踪它们。我认为如果有一个共享和非共享实例的注册选项,那么它仍然是一个简单的Ioc。我猜它只需要不在容器中添加创建的实例就行了?您的解决方案只有在未使用构造函数注入的情况下才有效(这不是一件好事)。如果容器负责注入依赖项,就没有办法告诉它创建新实例并将它们注入构造函数,是吗?我试图避免在代码中调用SimpleIoC.GetInstance(),因为依赖于容器是一种不好的做法。如何告诉SimpleIoC始终创建新实例并注入它们,而不是缓存一个实例?在我看来,在SimpleIoC.Register中使用一个简单的“cache”标志就足够了。嗨,Obalix,我知道我可以使用另一个容器,但由于我使用的是MVVM light,如果我不需要unity(或任何其他IoC)提供的高级功能,我不想引入另一个dll来加载。我在这里的想法是,这不是一个高级特性,它不需要太多的编码来实现它,而且它是一个将被频繁使用的特性。我也在
public class MyObjectUser
{
    MyObject _myObject;
    public MyObjectUser(IMyObjectFactory factory)
    {
        _myObject = factory.CreateObject();
    }
}