2013-04-06 83 views
1

我有兩個類,服務器和客戶端。服務器需要在多個線程中實例化客戶端,並且客戶端有一個需要提供自定義實現的虛擬成員。我的問題是。如果Client類是Server類的嵌套類,或者我應該使用接口和依賴注入來將自定義實現引入Server類。現在Client類還有許多私有方法提供了一些不應該改變的標準邏輯。我應該使用嵌套類還是IoC容器?

public class Server 
{ 
    public void DoWork() 
    { 
     for (var i = 0;i < 10; i++) 
     { 
      Client client = new Client(); 
      client.Process(i); 
     } 
    } 
} 

public class Client 
{ 
    private void doSomething() 
    { 
     ... 
    } 

    // Needs to be overridden and provide custom logic 
    public virtual string Process(int i) 
    { 
     return i.ToString(); 
    } 
} 

工作例如:

public interface IClient 
{ 
    string Process(string message); 
} 

public abstract class Client : IClient 
{ 
    public virtual string Process(string message) 
    { 
     return message; 
    } 
} 

public class CustomClient : Client 
{ 
    public CustomClient() { } 

    public override string Process(string message) 
    { 
     return string.Format("Custom Client:{0}", message); 
    } 
} 

public class Server 
{ 
    private Func<IClient> createClient;  

    public Server() { } 

    public Server(Func<IClient> client) 
    { 
     createClient = client; 
    } 

    public void DoWork() 
    { 
     for (var i = 0; i < 10; i++) 
     { 
      IClient = client = createClient(); 
      client.Process(string.Format("Client #{0}", i)); 
     } 
    } 
} 

測試計劃......你會步,看它擊中一個CustomClient

class Program 
{ 
    static void Main(string[] args) 
    { 
     Func<CustomClient> factory =() => new CustomClient(); 
     var server = new Server(factory); 
     server.DoWork(); 
    } 
} 
+1

如果服務器需要創建一個客戶端,我會傳遞一個工廠方法到服務器供它使用。所以我會去依賴注入。 – 2013-04-06 16:58:30

+0

您可以在(SRP)中傳遞依賴關係,但它不一定是要啓動的接口。 – 2013-04-06 16:59:19

+0

因此可以說我使用DI。如果Client類需要或多或少是一個抽象類,那麼這將如何工作?我會有一個接口讓我們說IClient,然後是一個繼承自IClient的抽象類,它有默認的實現。正如我所說,它有很多私有方法,不會因爲只有一種虛擬方法而改變。我可以在從接口繼承的抽象類的子類上使用DI嗎? – ewahner 2013-04-06 17:18:13

回答

1

如果服務器需要創建一個客戶端,我會傳遞一個工廠方法到服務器供它使用。所以我會去依賴注入。

例如:你可以傳遞給Server構造一個Func<IClient>並將其分配給所謂的,比如說,createClient私有字段,然後代替

Client client = new Client(); 

使用

IClient client = createClient(); 

這樣,你可以完全分離服務器和客戶端。

我更喜歡使用簡單的Func委託而不是完整的工廠類,因爲這是(a)更容易使用和(b)更鬆散耦合的。

+0

是否有理由通過工廠方法或工廠而不僅僅是一個實例? – 2013-04-06 19:02:22

+0

抽象類Client必須通過委託工廠繼承和實例化,因爲Server類是具體類。我無法創建它的一個實例,因爲Client類可以用許多不同的方式實現。 – ewahner 2013-04-07 22:04:36

1

問題的依賴是否應注射或已固定一個簡單的答案 - 一個提供變化主題的邏輯的類是一個被注入的候選者。另一方面,如果你不打算改變邏輯,你可以使用固定類型進行編碼,就像你使用大多數基類庫一樣。

您所描述的內容聽起來像DI的場景 - 如果您允許覆蓋客戶端類,那麼您認爲可以進行更改。 DI是同時處理依賴和變更的最明顯方式之一。