在C#中的多个对象之间共享实例化的类

时间:2011-03-30 00:39:00

标签: c# wpf

我目前有一个类,当我启动程序时,我会实例化它。该类本身将创建一个新线程,并开始从路由器搜索广播。

我有其他窗口,除了MainWindow之外,它需要能够访问存储在此类实例中的数据。但是,我不确定其他窗口如何引用这些数据。

还有其他方法可以存储此类的实例,以便它可以在应用程序范围内访问吗?我需要它在应用程序的其余部分启动时才能正确启动,因此在第一个窗口中实例化类似乎是合乎逻辑的(对我而言)。

namespace Lalu_WPF
{
    public partial class MainWindow : Window
    {
        // data storage for program
        public FindRouter finder = new FindRouter();

        public MainWindow()
        {
......

7 个答案:

答案 0 :(得分:8)

不要制作Singleton(注意大写字母)。它在多线程环境(muttable Singletons)中容易出错,而且不适合测试。

您有什么要求?

您是否必须在一个应用程序中拥有一个对象或在整个CLR中拥有一个对象?

我打赌第一个。

在App类(App.xaml.cs)中创建一个对象,然后通过getter

访问它
App MyApplication = ((App)Application.Current);
MyApplication.Router;

答案 1 :(得分:4)

Don't使用Singletonunit testing hardyour code surprising

为需要访问实例的实例提供类。这意味着需要此单个实例的每个类都应该通过构造函数参数或setter接受。创建该类的人随后负责提供依赖。这称为Dependency Injection

答案 2 :(得分:1)

您可以使该类成为单例,这样您就可以在整个应用程序中访问同一个实例。您可以在msdn网站here

上看到一个示例

答案 3 :(得分:0)

你有程序课吗?在我执行的Windows窗体项目中,变量包含在程序public static readonly成员或public static属性中{{1}只有。

答案 4 :(得分:0)

你所说的听起来像是Singleton的设计模式。你可以创建一个单例对象,一个静态类,或者(我喜欢的)一个Monostate对象(一个封装静态类或单个实例的对象),如下所示:

public class SingletonWidget
{
    private static readonly Implementation SingleInstance ;

    public void DoSomething( int someValue )
    {
        SingleInstance.DoSomething( someValue ) ;
        return ;
    }
    public int SomeProperty
    {
        get
        {
            return SingleInstance.SomeProperty ;
        }
        set
        {
            SingleInstance.SomeProperty = value ;
        }
    }

    static SingletonWidget()
    {
        SingleInstance = new Implementation() ;
        return ;
    }

    private class Implementation
    {
        public void DoSomething( int someValue )
        {
            // ...
        }
        public int SomeProperty { get ; private set ; }
    }

}

用法看起来像普通对象即时:

SingletonWidget foo = new SingletonWidget() ;

foo.DoSomething(3) ;

但是在幕后,只有一个实例。从静态类或单例变换是微不足道的,因为只需要更改包装器。构建存根或模拟也很容易。

这很容易

答案 5 :(得分:0)

尝试DI框架或服务定位器的一些不太复杂的实现。这将允许您在整个应用程序中提供需要它的实例,而无需在单例中进行硬编码,这样就可以编写测试。

我知道Ninject至少为应用程序范围内的单个实例提供支持。我没有在WPF应用程序中使用它,但我不明白为什么不这样做。

作为服务定位器的基本示例,您可以执行以下操作。我已经调用了共享类Foo

public interface IFoo { ... }
public class Foo { ... }

public class ServiceLocator
{
    IFoo _foo = new Foo();
    public IFoo GetFoo() { return _foo; }
}

public class DependsOnFoo
{
    public IFoo Foo = ServiceLocator.GetFoo();
    ...
}
默认情况下,

DependsOnFoo.FooFoo的共享实例,但在编写自动化测试时,您可以将它与存根或模拟交换出来:

var testTarget = new DependsOnFoo();
testTarget.Foo = mockFooImplementation;
// now testTarget isn't bound to the Foo implementation

答案 6 :(得分:0)

据我所知,您的问题是如何存储对您的finder的引用,而不是如何创建它。如果是这种情况,我建议使用IDictionary Application.Current.Properties属性,这只是应用程序范围属性的集合。在启动时,您可以创建对象并存储对它的引用,如下所示:

Application.Current.Properties["finder"] = new FindRouter();

然后,在程序的任何地方,您都可以像

一样访问它
FindRouter finder = (FindRouter)Application.Current.Properties["finder"];

希望这有帮助。