我目前有一个类,当我启动程序时,我会实例化它。该类本身将创建一个新线程,并开始从路由器搜索广播。
我有其他窗口,除了MainWindow之外,它需要能够访问存储在此类实例中的数据。但是,我不确定其他窗口如何引用这些数据。
还有其他方法可以存储此类的实例,以便它可以在应用程序范围内访问吗?我需要它在应用程序的其余部分启动时才能正确启动,因此在第一个窗口中实例化类似乎是合乎逻辑的(对我而言)。
namespace Lalu_WPF
{
public partial class MainWindow : Window
{
// data storage for program
public FindRouter finder = new FindRouter();
public MainWindow()
{
......
答案 0 :(得分:8)
不要制作Singleton(注意大写字母)。它在多线程环境(muttable Singletons)中容易出错,而且不适合测试。
您有什么要求?
您是否必须在一个应用程序中拥有一个对象或在整个CLR中拥有一个对象?
我打赌第一个。
在App类(App.xaml.cs)中创建一个对象,然后通过getter
访问它App MyApplication = ((App)Application.Current);
MyApplication.Router;
答案 1 :(得分:4)
Don't使用Singleton,unit testing hard和your 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.Foo
是Foo
的共享实例,但在编写自动化测试时,您可以将它与存根或模拟交换出来:
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"];
希望这有帮助。