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

问题描述:

我目前有一个类,当我启动我的程序时实例化。该类本身将创建一个新线程并开始搜索来自路由器的广播。在C#中的多个对象之间共享一个实例化的类

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

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

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

     public MainWindow() 
     { 
...... 
+0

will [Singleton pattern](http://en.wikipedia.org/wiki/Singleton_pattern)能工作吗? – 2011-03-30 00:43:24

+4

每次有人让单身测试人员杀了一个kitteh – 2011-03-30 00:56:23

别不要让Singleton(注意大写字母)。它在多线程环境(可变单例)中很容易出错,而且不适合测试。

您有什么要求?

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

我敢打赌第一个。

让你的App类(App.xaml.cs)一个对象,然后通过getter存取权限它

App MyApplication = ((App)Application.Current); 
MyApplication.Router; 
+0

如果您不使其线程安全,那么在多线程环境中只会出现错误。我不认为这是不使用它的好理由。 – 2011-03-30 01:09:07

+0

这是小心使用它的好理由。而且,测试也很困难。当你不能覆盖它时,必须建立一个模拟对象? – 2011-03-30 01:26:50

+0

这比单身人士好得多。 – Four 2011-03-30 01:37:33

您是否有Program课程?在我所做的Windows Forms项目中,变量如程序publicstaticreadonly成员或publicstatic属性仅限于get

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

+0

单身人士是一个不好的模式,或者我应该说容易的模式。我认为它在恶劣的情况下经常被使用。此外,另一种方法,比如将实例传递给构造函数会使其比单例更具可测性。 – Four 2011-03-30 01:35:45

你在说什么听起来像是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 ; } 
    } 

} 

使用看起来像普通对象instantation :

SingletonWidget foo = new SingletonWidget() ; 

foo.DoSomething(3) ; 

但是在封面下面,只有一个实例挂着。因为只有包装器需要更改,因此从静态类或单例更改很重要。建筑存根或嘲笑也非常容易。

它可以很容易地

尝试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 

Don't使用Singleton,它使unit testing hardyour code surprising

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

+0

我会用其中的所有其他建议。 – Four 2011-03-30 01:38:21

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

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

然后,在你的程序中的任何地方,你可以访问它像

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

希望这有助于。