2011-03-30 83 views
3

我目前有一個類,當我啓動我的程序時實例化。該類本身將創建一個新線程並開始搜索來自路由器的廣播。在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

回答

6

別不要讓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

0

您是否有Program課程?在我所做的Windows Forms項目中,變量如程序publicstaticreadonly成員或publicstatic屬性僅限於get

1

您可以讓該類成爲單例,這樣您就可以在整個應用程序中訪問同一個實例。你可以在msdn網站上看到一個例子here

+0

單身人士是一個不好的模式,或者我應該說容易的模式。我認爲它在惡劣的情況下經常被使用。此外,另一種方法,比如將實例傳遞給構造函數會使其比單例更具可測性。 – Four 2011-03-30 01:35:45

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 ; } 
    } 

} 

使用看起來像普通對象instantation :

SingletonWidget foo = new SingletonWidget() ; 

foo.DoSomething(3) ; 

但是在封面下面,只有一個實例掛着。因爲只有包裝器需要更改,因此從靜態類或單例更改很重要。建築存根或嘲笑也非常容易。

它可以很容易地

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 
4

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

給出需要訪問實例實例的類。這意味着每個需要這個單一實例的類都應該通過構造函數參數或setter來接受。然後創建這個類的人負責提供依賴關係。這被稱爲Dependency Injection

+0

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

0

據我所知你的問題是如何存儲對你的發現者的引用,而不是如何創建它。如果是這種情況,我會建議使用IDictionary Application.Current.Properties屬性,這只不過是應用程序範圍屬性的集合。在啓動時,您可以創建對象並存儲這樣的一個引用:

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

然後,在你的程序中的任何地方,你可以訪問它像

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

希望這有助於。

相關問題